这个问题最好用例子说明
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;
}
Run Code Online (Sandbox Code Playgroud)
就目前而言,不能使用赋值运算符,因为推导存在问题U(至少我认为这是错误告诉我的).如何编译代码?我也尝试过为expression这种方法创建一个转换构造函数variable,但也没有用.我想避免继承expression,因为它在实践中比其他两个更重.
该operator=*是其他高级用法,如添加的立场operator*(expression<T>, expression<U>),并能与调用它们a*b.
我尝试过Clang trunk(8.0.0)和GCC trunk(9.0.0)-std=c++17,以及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.
Run Code Online (Sandbox Code Playgroud)
GCC消息:
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;
| ^
Run Code Online (Sandbox Code Playgroud)
*正如所指出的那样,通常会operator=返回T&,但是我这个类的用例(至少目前为止)不允许链接.
您正在尝试调用函数模板实例化,该实例化需要进行expression<U>后推导U.U但是,没有推论,因为你没有通过expression<U>.你通过了variable<int>.确实variable<int>可以转换为expression<int>,但你没有触发它.在尝试转换之前,扣除失败(因为如何从完全不同的类型推断出它?).
要快速解决,b=expression<int>(a) 应该解决它.你可以考虑decay()为你做一个函数来实现这个功能,实际上是你自己的左值到右值的转换!这可能就像你可以做到的那样简洁,没有进一步的架构变化.
除此之外,我没有为您提供具体的解决方案,只是说您需要根据您的要求重新考虑这个类设计.