在SFINAE函数模板中将struct作为参数转发引用



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

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或使用基本整数代替结构体(通过适当的模板代码更改)时,它确实可以编译。

这里的问题是,对于转发引用,由于val0是左值,T被推断为S&,而不是S。这导致std::is_same_v<T, S>失败,因为SS&不同。要解决这个问题,您可以使用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;
}

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

最新更新