C++ 中的函数模板专用化和右值引用
Function template specialization and rvalue reference in c++
#include <iostream>
struct Cls{double dval = 0;};
template<typename T>
void foo(T&& Obj) {
//..... use Obj
}
void foo(const Cls& Obj) {
//..... use Obj.dval
}
//void foo(Cls Obj) {
// //..... use Obj.dval
//}
int main()
{
Cls Obj;
const Cls cv_Obj;
foo(Obj); //case 1
foo(Cls{}); //case 2
foo(cv_Obj); //case 3
foo(10.10);
}
如果函数参数const ref
,则Cls
的模板专用化将失败(case 1, case 2
),但by val
适用于所有情况。
除了pass by val
之外,还有其他方法可以处理所有cases
(所有值类型)的专用化吗?
您可以使用
SFINAE 解决此问题,但是摆脱 _struct
上的重载并为operator<<
定义重载会容易得多:
std::ostream& operator<<(std::ostream& os, const _struct& obj)
{
os << obj.dval;
return os;
}
使用 SFINAE 解决的一种可能性是检查在一个重载中直接输出Obj
的有效性,并根据另一个重载中的_struct
检查类型:
template<typename T>
auto foo(T&& Obj) -> decltype(std::cout<<Obj, void()) {
std::cout<<Obj;
}
template<typename T,
std::enable_if_t<std::is_same<_struct, std::decay_t<T>>::value>* = nullptr>
void foo(T&& Obj) {
std::cout<<Obj.dval;
}
你需要一个帮助程序结构:
#include <iostream>
struct _struct{double dval = 0;};
template<typename T, typename Enable = void>
struct bar {
bar(T&& Obj) {
std::cout<<Obj;
}
};
template<typename T>
struct bar<T, typename std::enable_if<std::is_same<typename std::decay<T>::type, _struct>::value>::type> {
bar(T&& Obj) {
std::cout<<Obj.dval;
}
};
template<typename T>
void foo(T&& Obj) {
bar<T>(std::forward<T>(Obj));
}
int main()
{
_struct Obj;
const _struct cv_Obj;
foo(1);
foo(Obj); //case 1
foo(_struct{}); //case 2
foo(cv_Obj); //case 3
foo("test");
}
相关文章:
- .cpp和.h文件中的模板专用化声明
- 将对象数组的引用传递给函数
- 什么时候在C++中返回常量引用是个好主意
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 何时在引用或唯一指针上使用移动语义
- 具有常量引用参数的函数模板专用化
- 将返回类型专用化为 void 或 const 左值引用
- 模板专用化会导致未定义的引用错误
- 对专用模板成员的未定义引用
- 通过引用调用模板专用化
- 使用模板专用化来比较指针引用
- 为什么模板别名专用化取决于引用它的上下文
- 静态 constexpr 模板成员在专用时提供未定义的引用
- 共享库:具有部分模板专用化和显式模板实例化的未定义引用
- 专用纯虚拟模板函数(未定义引用)的另一个问题
- 右值和右值引用的模板专用化
- C++ 中的函数模板专用化和右值引用
- qt专用插槽moc未定义引用错误
- std::引用类型的可选专用化
- 无法引用专用静态成员变量:编译器错误