允许模板参数仅为特定类型并基于它来决定操作

Dar*_*lyn 5 c++ templates

假设我有两节课MyClass_one,MyClass_two

我的功能只接受它们作为第一个参数

template<typename T,typename ...Ts>
void doSomething(T one, Ts...two){}
Run Code Online (Sandbox Code Playgroud)

现在为了简单起见,如果参数oneMyClass_one它应该打印"im one"如果MyClass_two它应该打印"im two".

如何实际实现这一目标?我提出的唯一解决方案是非常丑陋,并没有包含编译错误抛出:

template<typename T> isOne{ static const bool value = false}
template<> isOne<MyClass_one>{ static const bool value = true}

template<typename T> isTwo{ static const bool value = false}
template<> isTwo<MyClass_two>{ static const bool value = true}

template<typename T, typename ... Ts>
void doSomething(T one, Ts...two){
  if( isOne<T>::value ) { cout << "im one" << endl;}
  else if ( isTwo<T>::value){ cout <<"im two" << endl;}
}
Run Code Online (Sandbox Code Playgroud)

但是如何实现没有超载的编译器错误检查(多重定义doSomething()功能)例如功能如果别的东西比将无法编译MyClass_oneMyClass_two传递.

感谢帮助.

tma*_*ric 5

如果你可以使用C++ 17,你可以使用if constexpr:

template<typename T, typename ... Ts>
void doSomething(T one, Ts...two){
  if constexpr ( isOne<T>::value ) { cout << "im one" << endl;}
  else if constexpr ( isTwo<T>::value){ cout <<"im two" << endl;}
}
Run Code Online (Sandbox Code Playgroud)

当然,isOne<T>::valueisTwo<T>::value需要是static constexpr变量.

如果您要检查的多种类型的第一函数参数,同样的方法保存,惟独没有必要像isOneisTwo,你可以用std::is_same_v,看看第一个参数是MyClassOne或者MyClassTwo:

#include <iostream> 
#include <type_traits>
#include <vector> 

class MyClassOne {}; 
class MyClassTwo {}; 

template<typename T, typename ... Ts>
void doSomething(T one, Ts...two){
  if constexpr ( std::is_same_v<T, MyClassOne> ) 
    std::cout << "im one" << std::endl;
  else if constexpr ( std::is_same_v<T, MyClassTwo> )
    std::cout <<"im two" << std::endl;
  else
    static_assert(false, "Only MyClassOne and MyClassTwo are permitted first arguments.");
}
int                                                                                                                                         
main(int argc, char **argv) { 

    MyClassOne one; 
    MyClassTwo two; 

    doSomething(one, 1.5, two); 
    doSomething(two, 'c', one);

    std::vector<MyClassOne> onesVector;
    doSomething(onesVector, 1.0); 

}  
Run Code Online (Sandbox Code Playgroud)

std::is_same_v<A,B>true如果类型AB相同,则得到一个值.这回答了你的问题"如果参数一是MyClass_one它应该打印"im one"如果它的MyClass_two它应该打印"im two".",并且如果第一个参数是任何类型不同于et myClassOne或者,则在编译时失败myClassTwo.

编辑:添加一个static_assert确保编译失败,如果第一个参数是除了MyClassOne或之外的任何其他内容MyClassTwo,正如评论中Justin Time所建议的那样.