SFINAE检查运算符+=
SFINAE check for operator+=
如果缺少operator+=
,我将尝试从过载集中消除过载。
我知道如何检查T+T
是否合法:
template<typename T,
typename CheckTplusT = decltype(std::declval<T>() + std::declval<T>())>
void foo(T a, T b, ...)
{
a = a + b;
}
但这对+=
不起作用
template<typename T,
typename CheckTplusT = decltype(std::declval<T>() += std::declval<T>())>
void foo(T a, T b, ...)
{
a += b;
}
这是可以通过在decltype
中使用另一个表达来解决的吗?还是我需要另一个SFINAE构建体?
我需要从重载集中消除这一点的原因是,它与另一个重载冲突,后者接受一个函子作为+=
的替代。编译器是VS2013、gcc4.8
我会把第二个表单写成:
template<typename T>
auto foo(T a, T b, ...) -> decltype( a+=b, void() )
{
a += b;
}
如果表达式a+=b
有效,则decltype(a+=b, void())
的推导类型将仅为void
,否则将导致SFINAE。
好吧,即使在第一种形式中,我也会使用尾随返回类型的方法。
您需要+=
左侧的lvalue
,但您的解决方案具有x值。正如dyp在评论中所说,您可以使用declval<T&>
来获得一个左值。这很好用(刚刚测试过):
template<typename T,
typename CheckTplusT = decltype(std::declval<T&>() += std::declval<T>())>
void foo(T a, T b, ...)
{
}
这个怎么样?这是CCD_ 12之前使用的方法。
template<typename T,
typename CheckTplusT = decltype(*(T*)nullptr += std::declval<T>())>
void foo(T a, T b, ...)
{
a += b;
std::cout << "foo with +=" << std::endl;
}
添加此main()函数:
int main()
{
int x = 1, y = 2;
foo( x, y );
}
这就是编译器错误:
main.cpp: In function int main(): main.cpp:15:15: error: no matching
function for call to foo(int&, int&)
foo( x, y );
^ main.cpp:15:15: note: candidate is:
main.cpp:7:6: note: template<class T, class CheckTplusT> void foo(T, T, ...) void
foo(T a, T b, ...)
^ main.cpp:7:6: note: template argument deduction/substitution failed:
main.cpp:6:60: error:
using xvalue (rvalue reference) as lvalue
typename CheckTplusT = decltype(std::declval<T>() += std::declval<T>())>
关键线路为using xvalue (rvalue reference) as lvalue
这是清除的文档
这个变通方法对我有效:
template<typename T,
typename CheckTpluseqT = decltype(*std::declval<T*>() += *std::declval<T*>())>
void foo(T &a, T b, ...)
{
a += b;
}
int main()
{
int a = 1, b = 2;
foo( a, b );
std::cout << a << std::endl;
}
输出3
当然,您也可以使用declval<T&>
。
相关文章:
- SFINAE 检查模板参数运算符
- 检查类是否具有可能重载的函数调用运算符
- 在编写自己的流运算符时,如何检查当前的 ostream dec/hex 模式?
- 如何检查运算符 != 模板参数是否存在 C++ 17?
- 如何在C++编译时检查运算符的特定重载是否存在
- 重载泛型类型的模板类时检查运算符=时的自赋值
- 检查运算符()是否存在
- 检查运算符是否在C++中过载
- 不带运算符==的类相等性检查
- 如何使用sfinae检查,类型是否有运算符()?
- C++ 如何重载关系运算符以检查两个对象是否相同
- 检查 QTextStream::运算符>>是否失败
- C++SFINAE运算符/函数结果类型检查
- 检查C 11中的运算符的最佳方法
- 提升概念检查运算符()重载
- 是具有复制和交换习惯用法的复制赋值运算符,建议进行自赋值检查
- 检查错误时重载>>运算符中的无限循环
- c++:执行动态分配的新运算符检查内存安全性
- 在检查 while 循环中与"运算符!="不匹配
- 如何检查运算符优先级