我从编译器收到以下错误:error: no match for 'operator+' (operand types are 'Expected<double>' and 'Expected<double>')
预期是类型或异常。
template<typename T>
class Expected
{
template<typename U>
Expected<U> apply(std::function<U(T)> f)
{
if(!valid) return std::get<std::exception_ptr>(state);
try
{
return f(std::get<T>(state));
}
catch(...)
{
return std::current_exception();
}
}
};
#define MixedMode(op)\
template<typename T, typename U, typename V>\
Expected<U> op(Expected<T> t, Expected<V> v)\
{\
return t.apply([&](T myT){return op(v,myT);});\
}\
template<typename T, typename U, typename V>\
Expected<U> op(Expected<T> t, V v)\
{\
return t.apply([&](T myT){return op(myT,v);});\
}\
\
template<typename T, typename U, typename V>\
Expected<U> op(V v, Expected<T> t)\
{\
return t.apply([&](T myT){return op(v,myT);});\
}\
MixedMode(operator+)
int main()
{
Expected<double> a;
Expected<double> b;
a + b;
}
我相信我的头文件已经做得足够让他们重载并将它们加在一起。在第一个我期待两个模板加在一起。在我的主文件中,我只是打电话:
Expected<double> a;
Expected<double> b;
std::cout << a + b << std::endl;
然后抛出错误。在我添加Expected<U> op(Expected<T> t, Expected<V> v)\
部分代码之前,我能够编译并运行,如果我有一个名为operator T() { return value(); }
的函数,它会隐式地将Expected<T>
转换为传入的任何类型。但是,我意识到我的apply
函数从未被使用过。不仅如此,当我检查a+b
的类型时,我返回了double
而不是Expected<double>
,因此我删除了operator T()
函数,编译器通知我它没有&{ #39;知道如何将两个Expected<T>
加在一起。
如何修复此错误?我整天都在反对这一切。
答案 0 :(得分:0)
模板函数的主体从不用于推导模板参数。无法从参数中推断出U
,因此会忽略您的+
重载。
#define MixedMode(op)\
template<typename T, typename V>\
auto op(Expected<T> t, Expected<V> v)\
{\
return t.apply([&](T myT){return op(v,myT);});\
}\
template<typename T, typename V>\
auto op(Expected<T> t, V v)\
{\
return t.apply([&](T myT){return op(myT,v);});\
}\
template<typename T, typename V>\
auto op(V v, Expected<T> t)\
{\
return t.apply([&](T myT){return op(v,myT);});\
}
这将无法编译,但这是因为您写错了apply
。
std::function
不是lambda,lambda不是std::function
。如果你推断std::function
999/1000次的类型你搞砸了,brcause std::function
是关于类型擦除的,而演绎是关于类型演绎的,而那些是相反的概念
更重要的是,你正在向后组合它们,而且它们并不是那样构成的。
template<class F>
Expected<std::invoke_result_t<F&,T&>> apply(F f){
或类似的东西。