2017-11-18 119 views
0

我从编译器得到以下错误: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()函数,编译器通知我它不知道如何将两个Expected<T>一起添加。

我该如何解决这个错误?我一整天都在殴打我。

+1

你可以把它拍成[mcve]吗?例如,如果没有这个宏,它可能不起作用,你不需要在课堂上的所有东西。你可能会[击败它](https://ideone.com/cNcRpF),仍然会有相同的错误。为什么试验所有额外的噪音? – user4581301

+0

@ user4581301我可以尝试将它打败成一个我将排除'operator <<'的最小例子,然后我意识到我需要它,所以没有人会自己写它。我可以只用你的吗? – Sailanarmo

+0

@ user4581301我也有这个宏,因为我打算使用除'+ =, - =,='之外的所有运算符。所以我想我应该让它现在是它的样子。 – Sailanarmo

回答

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错了。

A std::function不是拉姆达,而拉姆达不是std::function。如果你正在推断你正在搞的std::function 999/1000次的类型,因为std::function是关于类型删除和扣除是关于类型扣除,并且那些是相反的概念

更重要的是,你是在向后写作,而他们不是这样写的。

template<class F> 
Expected<std::invoke_result_t<F&,T&>> apply(F f){ 

或类似的东西。

+0

对不起,我花了一段时间来围绕你的答案。但我仍不确定如何应用写入不正确。如果结果不是例外,请尝试执行我正在假设的操作是'期望 +预期'并返回结果。如果有的话,赶上例外。 我也从来没有见过'std :: invoke_result_t'你会不会解释这是如何工作的?最后,如果应用程序正确完成,其余的编译器错误会消失吗? – Sailanarmo

+0

我给出了更正的代码。什么不清楚呢?我给了一个修复申请。我修正了我可以发现的任何错误。你的问题缺乏[mcve],所以我不知道还有哪些错误,也没有在线编译器上测试我的代码,所以我可能有错别字。您是否尝试使用'std :: invoke_result'搜索并阅读[this site](http://en.cppreference.com/w/cpp/types/result_of)?如果您在阅读后有新问题,可以通过“提问”按钮询问他们,或者搜索他们是一个很好的计划;评论太简短了。 – Yakk

相关问题