使用别名将通用引用限制为单一类型
limit universal reference to a single type using aliasing
我有一个 class 的成员函数,我想在其中对其中一个参数使用完美转发。但是,转发给的函数只接受一个 c2Type
类型的参数,所以我希望调用函数也只接受 c2Type
参数,但显然必须保留通用引用才能执行转发。似乎可以使用像这样的默认模板参数来完成:
class c2Type
{
// some data members...
};
template<typename T, typename isC2Type = typename std::enable_if<
std::is_same<c2Type, typename std::decay<T>::type>::value>::type>
void configurationMessageHandler(T&& message)
{
// some stuff...
mapAddress(std::forward<c2Type>(message));
}
mapAddress(c2Type&& message)
{
// do stuff...
};
但是,我需要在几个成员函数上检查这个类型,而且这么长的模板看起来不友好且不可读。我想要的是为 isC2Type
创建一个别名,例如
template<typename T>
using isC2Type = typename std::enable_if<
std::is_same<c2Type, typename std::decay<T>::type>::value>::type;
我认为 configurationMessageHandler
模板看起来像
template<typename T, isC2Type<T>>
但这不能编译。在这种情况下如何正确使用别名?
希望对您有所帮助。
template<class U, class T,
class= std::enable_if_t<std::is_same<std::decay_t<T>, U>::value, T>>
using LimitTo = T;
template<class T>
void configurationMessageHandler(LimitTo<c2Type,T>&& message){
// some stuff...
mapAddress(std::forward<T>(message));
//!! Use T because the reference of c2Type maybe has cv-qualify
}
即使有很多参数,例如:
void foo(int);
template<class A, class B, class C>
void foo(LimitTo<int,A>&& , LimitTo<float,B>&& , LimitTo<bool,C>&& );
template<class T>
void foo(LimitTo<string,T>&& );
但是,这个技巧有一些缺陷:
请注意,在某些情况下它不会起作用。这会导致某些编译器出现致命错误。不知道为什么。
template<class...Args>
void foo(LimitTo<double,Args>&&... args){}
使用默认参数以避免歧义,例如关于此类构造函数:
template<class T>
Ctor(LimitTo<string,T>&&,string* =nullptr) {} //string* or anything else
template<class T>
Ctor(LimitTo<double,T>&&, double* =nullptr) {}
继承构造函数会导致一些问题,因为默认参数不能被继承。所以将其更改为:
template<class T>
Ctor(LimitTo<string,T>&&,string*) {}
template<class T>
Ctor(LimitTo<double,T>&&, double*) {}
我有一个 class 的成员函数,我想在其中对其中一个参数使用完美转发。但是,转发给的函数只接受一个 c2Type
类型的参数,所以我希望调用函数也只接受 c2Type
参数,但显然必须保留通用引用才能执行转发。似乎可以使用像这样的默认模板参数来完成:
class c2Type
{
// some data members...
};
template<typename T, typename isC2Type = typename std::enable_if<
std::is_same<c2Type, typename std::decay<T>::type>::value>::type>
void configurationMessageHandler(T&& message)
{
// some stuff...
mapAddress(std::forward<c2Type>(message));
}
mapAddress(c2Type&& message)
{
// do stuff...
};
但是,我需要在几个成员函数上检查这个类型,而且这么长的模板看起来不友好且不可读。我想要的是为 isC2Type
创建一个别名,例如
template<typename T>
using isC2Type = typename std::enable_if<
std::is_same<c2Type, typename std::decay<T>::type>::value>::type;
我认为 configurationMessageHandler
模板看起来像
template<typename T, isC2Type<T>>
但这不能编译。在这种情况下如何正确使用别名?
希望对您有所帮助。
template<class U, class T,
class= std::enable_if_t<std::is_same<std::decay_t<T>, U>::value, T>>
using LimitTo = T;
template<class T>
void configurationMessageHandler(LimitTo<c2Type,T>&& message){
// some stuff...
mapAddress(std::forward<T>(message));
//!! Use T because the reference of c2Type maybe has cv-qualify
}
即使有很多参数,例如:
void foo(int);
template<class A, class B, class C>
void foo(LimitTo<int,A>&& , LimitTo<float,B>&& , LimitTo<bool,C>&& );
template<class T>
void foo(LimitTo<string,T>&& );
但是,这个技巧有一些缺陷:
请注意,在某些情况下它不会起作用。这会导致某些编译器出现致命错误。不知道为什么。
template<class...Args> void foo(LimitTo<double,Args>&&... args){}
使用默认参数以避免歧义,例如关于此类构造函数:
template<class T> Ctor(LimitTo<string,T>&&,string* =nullptr) {} //string* or anything else template<class T> Ctor(LimitTo<double,T>&&, double* =nullptr) {}
继承构造函数会导致一些问题,因为默认参数不能被继承。所以将其更改为:
template<class T>
Ctor(LimitTo<string,T>&&,string*) {}
template<class T>
Ctor(LimitTo<double,T>&&, double*) {}