无法推导出模板参数'T'

问题描述 投票:0回答:1

我试图在调用分配函数时使用 source_location::current() 作为默认参数来创建记录器库。

#include <iostream>
#include <source_location>
#include <type_traits>

template <class T>
struct log_helper { 
    log_helper(const T& o, std::source_location sl = std::source_location::current()) 
        : value(o), sl(sl) {}
    T value;
    std::source_location sl;
};

struct ratio_t {
    operator double() const {
        return ratio;
    }

    // ratio_t(double ratio = 0) : ratio(ratio) {
    //     printf("%p: construct\n", this);
    // }

    template<class T, class = typename std::enable_if_t<std::is_arithmetic_v<T>>>
    ratio_t& operator=(const log_helper<std::type_identity_t<T>>& o) {
        ratio = o.value;
        
        line = o.sl.line();
        func = o.sl.file_name();
        printf("file: %s line: %d\n", func.c_str(), line);

        return *this;
    }

    void clear() {
        ratio = 0.0f;
        line = 0;
        func.clear();
    }

    double get_ratio() const {
        return ratio;
    }

    uint32_t get_line() const {
        return line;
    }

    std::string get_func() const {
        return func;
    }
private:
    double ratio{0.0f};
    uint32_t line{0};

    std::string func;
};

int main() {
    ratio_t a;
    // a.operator=<double>(log_helper(1.0));
    // a.operator=<double>(1.0); // it works
    a = 1.0; // <- problem here
}

但我收到此错误:

b.cpp: In function 'int main()':
b.cpp:61:9: error: no match for 'operator=' (operand types are 'ratio_t' and 'double')
   61 |     a = 1.0;
      |         ^~~
b.cpp:23:14: note: candidate: 'template<class T, class> ratio_t& ratio_t::operator=(const log_helper<typename std::type_identity<_Tp>::type>&)'
   23 |     ratio_t& operator=(const log_helper<std::type_identity_t<T>>& o) {
      |              ^~~~~~~~
b.cpp:23:14: note:   template argument deduction/substitution failed:
b.cpp:61:9: note:   couldn't deduce template parameter 'T'
   61 |     a = 1.0;
      |         ^~~
b.cpp:13:8: note: candidate: 'ratio_t& ratio_t::operator=(const ratio_t&)'
   13 | struct ratio_t {
      |        ^~~~~~~
b.cpp:13:8: note:   no known conversion for argument 1 from 'double' to 'const ratio_t&'
b.cpp:13:8: note: candidate: 'ratio_t& ratio_t::operator=(ratio_t&&)'
b.cpp:13:8: note:   no known conversion for argument 1 from 'double' to 'ratio_t&&'

如果我显式地实现分配,则程序将起作用。然而这并不是我所期望的。我不知道还有其他扣除。那我该如何解决呢?

    a.operator=<double>(log_helper(1.0));
    a.operator=<double>(1.0);
c++ templates std
1个回答
0
投票

T
在这里处于非推导上下文中,因此您始终必须指定它。如果从声明中删除
std::type_identity_t
,则可以从
T
推导出
log_helper(1.0)
,但仍然不能推导出
1.0

在coliru上查看

© www.soinside.com 2019 - 2024. All rights reserved.