【问题标题】:Forwarding reference for struct as a parameter in a function template with SFINAE使用 SFINAE 将 struct 的引用作为函数模板中的参数转发
【发布时间】:2021-05-18 14:20:43
【问题描述】:

不知道为什么这段代码不能编译:

struct S{ int m; };

template<class T, class = std::enable_if_t<std::is_same_v<T, S>>>
T& operator+=(T&& arg0, int arg1)
{
    arg0.m += arg1;
    return arg0;
}

int main()
{   
    S val0{ 0 }; int val1{ 1 };
    val0 += val1;

    return 0;
}

但是,当 SFINAE 被移除或使用基本整数而不是结构时(通过适当的模板代码更改),它确实可以编译。

【问题讨论】:

    标签: c++ function templates sfinae enable-if


    【解决方案1】:

    这里的问题是对于转发引用,因为val0 是一个左值,T 被推断为S&amp;,而不是S。这会导致std::is_same_v&lt;T, S&gt; 失败,因为SS&amp; 不同。要解决此问题,您可以使用 std::decay_t 删除引用,如

    template<class T, std::enable_if_t<std::is_same_v<std::decay_t<T>, S>, int> = 0>
    T& operator+=(T&& arg0, int arg1)
    {
        arg0.m += arg1;
        return arg0;
    }
    

    我还调整了模板以使用默认的非类型参数而不是默认的类型参数。这样做可以让您更轻松地重载函数,因为与默认值不同,默认类型参数不是函数签名的一部分。

    【讨论】:

    • @oleksijp 我必须查看您正在使用的代码才能告诉您。如果您将T&amp;&amp; 更改为int&amp;&amp;,那么我可以告诉您,您不再有转发引用,而是右值引用。
    • 我想可能是因为整数存在非模板重载:D
    • @oleksijp 啊,是的,int&amp; operator +=(int, int) 已经被编译器定义了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-05
    • 1970-01-01
    • 1970-01-01
    • 2020-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多