假设我有两节课MyClass_one,MyClass_two
我的功能只接受它们作为第一个参数
template<typename T,typename ...Ts>
void doSomething(T one, Ts...two){}
Run Code Online (Sandbox Code Playgroud)
现在为了简单起见,如果参数one是MyClass_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_one或MyClass_two传递.
感谢帮助.
如果你可以使用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>::value和isTwo<T>::value需要是static constexpr变量.
如果您要检查的多种类型的第一函数参数,同样的方法保存,惟独没有必要像isOne和isTwo,你可以用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如果类型A和B相同,则得到一个值.这回答了你的问题"如果参数一是MyClass_one它应该打印"im one"如果它的MyClass_two它应该打印"im two".",并且如果第一个参数是任何类型不同于et myClassOne或者,则在编译时失败myClassTwo.
编辑:添加一个static_assert确保编译失败,如果第一个参数是除了MyClassOne或之外的任何其他内容MyClassTwo,正如评论中Justin Time所建议的那样.