c++ - 使用别名将通用引用限制为单一类型

标签 c++ c++11 perfect-forwarding universal-reference

我有一个类的成员函数,我想在其中对其中一个参数使用完美转发。然而,被转发到的函数只接受一个 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>&& ); 

但是,这个技巧也有一些缺陷:

  1. 请注意,在某些情况下它不会起作用。这会导致某些编译器出现 fatal error 。我不知道为什么。

      template<class...Args> 
      void foo(LimitTo<double,Args>&&... args){}
    
  2. 使用默认参数以避免歧义,例如关于此类构造函数:

      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*) {}

关于c++ - 使用别名将通用引用限制为单一类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27781088/

相关文章:

c++ - C++11 中的所有/大多数 setter 函数是否应该编写为接受通用引用的函数模板?

c++ - 完美转发类模板参数推导

c++ - 如何在没有 ARM 处理器的 Linux 上安装 TensorflowLite C++?

c++ - Visual Studio 2012 中的模板类实例化错误

c++ - 为什么我们总是检查输入是否失败而不是输出?

c++ - std::shared_ptr<T>:指向 T 的右值指针的隐式构造函数

c++ - 如何在 C++14 中编写通用转发 lambda?

c++ - 用正则表达式匹配中的另一个替换特定字符?

c++ - VS 2005 C++编辑CRichEditCtrl实例的内容

c++ - Google Protobuf 基于 C++ 的 Python 实现的性能