提问人:xujh 提问时间:9/4/2023 最后编辑:Marek Rxujh 更新时间:9/4/2023 访问量:82
无法推断模板参数“T”
couldn't deduce template parameter 'T'
问:
我正在尝试在调用分配函数时使用 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&&'
https://godbolt.org/z/9hbzejaWW
如果我显式实现赋值,progmma 将起作用。然而,这不是我所期望的。我没有意识到可能有任何其他扣除。那么我该如何解决呢?
a.operator=<double>(log_helper(1.0));
a.operator=<double>(1.0);
答:
1赞
Caleth
9/4/2023
#1
T
在这里处于非推导上下文中,因此您始终必须指定它。如果从声明中删除,则可以从 中推导出 ,但仍然不能。std::type_identity_t
T
log_helper(1.0)
1.0
评论
0赞
xujh
9/4/2023
谢谢你的回答。但是,这不就是用于这种隐式转换吗?坦率地说,我不太擅长它的使用std::type_identity_t
2赞
Caleth
9/4/2023
@xujh no,用于引入非演绎上下文std::type_identity_t
0赞
xujh
9/4/2023
我对你的说法有点困惑。我实际上是在尝试使用来避免显式转换。我不明白为什么它在这里不起作用。std::type_identity_t
1赞
Marek R
9/4/2023
@xujh这不是关于掩盖,而是关于模板演绎。由于引入了依赖类型(其下方是:),因此它阻止了编译器推导类型,并强制开发人员显式指定该类型。std::type_identity_t
typename std::type_identity::type
评论
double
log_helper<double>
double
log_helper<double>
log_helper
explicit
explicit
log_helper
double
log_helper<double>
ratio_t.operator=
log_helper<double>