【问题标题】:perfect forwarding function deduced conflicting error完美转发函数推导出冲突错误
【发布时间】:2018-04-17 01:22:45
【问题描述】:

我正在测试完美转发,我不明白为什么TEST_EQ(string("olleH"), s) 编译失败,但string("olleH") == s 编译通过。如何在此处修复我的 TEST_EQ 函数?

template<typename S>
static bool TEST_EQ(S&& a, S&& b) 
{
    return forward<S>(a) == forward<S>(b);      
}


int main()
{
 string s= "Hello";

 cout << TEST_EQ(string("olleH"), s) << endl;
 cout << (string("olleH") == s);

}

【问题讨论】:

    标签: c++ c++11 templates perfect-forwarding forwarding-reference


    【解决方案1】:

    根据forwarding reference的推演规则,当你尝试将TEST_EQ调用为TEST_EQ(string("olleH"), s)时,对于参数string("olleH"),它是一个右值,那么S将被推演为std::string;对于参数s,它是一个左值,那么S 将被推导出为std::string&amp;。推演结果冲突,调用失败。

    您可以添加另一个模板参数以避免这种推导冲突,例如

    template<typename S, typename T>
    static bool TEST_EQ(S&& a, T&& b) 
    {
        // if you need to check that S and T should be the same type
        static_assert(is_same_v<remove_cvref_t<S>, remove_cvref_t<T>>, "S and T must be the same type.");
    
        return forward<S>(a) == forward<T>(b);      
    }
    

    LIVE

    【讨论】:

    • 我不会建议修复,因为 OP 的目的是测试完美转发。我建议改为template &lt;typename S, typename T&gt; static bool TEST_EQ(S&amp;&amp; a, T&amp;&amp; b)
    • 另一种方法是禁用第二个参数的推导(see here)基本思路)
    【解决方案2】:

    好的,所以只要发现我不能通过一个模板参数传递两种不同的值类型。所以这个编译,也许加个static_assert来检查A,B类型会是一个很好的解决方案。

    template<typename A, typename B>
    static bool TEST_EQ(A&& a, B&& b) 
    {
        return (forward<A>(a) == forward<B>(b));      
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-05
      相关资源
      最近更新 更多