这个问题最好用例子来说明
template <typename T>
struct expression {
};
template <typename T>
struct variable {
operator expression<T>() const {
return {};
}
};
template <typename T>
struct member_variable {
template <typename U>
void operator=(const expression<U>&) {}
};
int main() {
variable<int> a;
member_variable<float> b;
b=a;
}
就目前而言,无法使用赋值运算符,因为推导 U
存在问题(至少我相信这是错误告诉我的)。我怎样才能编译代码?我还尝试为 expression
创建一个转换构造函数这需要 variable
那也不管用。我想避免继承 expression
,因为它在实践中比其他两个更重。
operator=
* 代表其他高级用法,例如添加 operator*(expression<T>, expression<U>)
并能够使用 a*b
调用它们.
我用 -std=c++17
尝试了 Clang trunk (8.0.0) 和 GCC trunk (9.0.0)和 MSVC 15.9.3。
clang :
prog.cc:28:6: error: no viable overloaded '='
b=a;
~^~
prog.cc:20:8: note: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'variable<int>' to 'const member_variable<float>' for 1st argument
struct member_variable {
^
prog.cc:20:8: note: candidate function (the implicit move assignment operator) not viable: no known conversion from 'variable<int>' to 'member_variable<float>' for 1st argument
struct member_variable {
^
prog.cc:22:10: note: candidate template ignored: could not match 'expression' against 'variable'
void operator=(const expression<U>&) {}
^
1 error generated.
海湾合作委员会消息:
prog.cc: In function 'int main()':
prog.cc:28:7: error: no match for 'operator=' (operand types are 'member_variable<float>' and 'variable<int>')
28 | b=a;
| ^
prog.cc:22:10: note: candidate: 'template<class U> void member_variable<T>::operator=(const expression<U>&) [with U = U; T = float]'
22 | void operator=(const expression<U>&) {}
| ^~~~~~~~
prog.cc:22:10: note: template argument deduction/substitution failed:
prog.cc:28:7: note: 'variable<int>' is not derived from 'const expression<T>'
28 | b=a;
| ^
prog.cc:20:8: note: candidate: 'constexpr member_variable<float>& member_variable<float>::operator=(const member_variable<float>&)'
20 | struct member_variable {
| ^~~~~~~~~~~~~~~
prog.cc:28:7: note: no known conversion for argument 1 from 'variable<int>' to 'const member_variable<float>&'
28 | b=a;
| ^
prog.cc:20:8: note: candidate: 'constexpr member_variable<float>& member_variable<float>::operator=(member_variable<float>&&)'
20 | struct member_variable {
| ^~~~~~~~~~~~~~~
prog.cc:28:7: note: no known conversion for argument 1 from 'variable<int>' to 'member_variable<float>&&'
28 | b=a;
| ^
* 如前所述,通常 operator=
返回 T&
,但是我对此类的用例是(至少目前)不允许链接。
最佳答案
您正在尝试调用一个采用 expression<U>
的函数模板实例化推导后U
.没有 U
不过,可以推断,因为您没有传递 expression<U>
.你传递的是 variable<int>
.确实variable<int>
可以转换为expression<int>
,但你没有触发它。在尝试转换之前推导失败(因为如何从完全不同的类型推导它?)。
要快速修复,b=expression<int>(a)
should solve it .你可以考虑做一个 decay()
为您执行此操作的函数,实际上是您自己的一种左值到右值转换!那可能是about as terse因为您可以在不进一步更改架构的情况下实现它。
除此之外,我没有具体的解决方案给你,只是说你需要根据你的要求重新考虑这个类的设计。
关于c++ - 如何将一个模板类隐式转换为另一个模板类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53650194/