仅允许模板参数为某些类型并基于它决定操作
Allowing template parameter to be only certain types and deciding action based on it
假设我有两个类MyClass_one
,MyClass_two
我有只接受它们作为第一个参数的函数
template<typename T,typename ...Ts>
void doSomething(T one, Ts...two){}
现在为了简单起见,如果参数 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;}
}
但是,如何在不重载的情况下实现编译器错误检查(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;}
}
当然,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);
}
如果A
和B
的类型相同,则std::is_same_v<A,B>
生成true
值。这回答了您的问题"如果参数 1 MyClass_one则它应该打印"im one",如果它MyClass_two它应该打印"im two".",并且如果第一个参数是与 etither myClassOne
或 myClassTwo
不同的任何类型的参数,则在编译时失败。
编辑:添加了一个static_assert
,如果第一个参数是除MyClassOne
或MyClassTwo
以外的任何其他参数,请确保编译失败,正如贾斯汀时间在评论中建议的那样。
无过载
但是这里的重载使代码变得简单:
template<typename ... Ts>
void doSomething(MyClass_one, Ts...two){
cout << "im one" << endl;
}
template<typename ... Ts>
void doSomething(MyClass_two, Ts...two){
cout <<"im two" << endl;
}
我建议将函数分成两部分。保持迭代部分doSomething
,并分离出您想要完成的实际事情。
template<typename T> void theThing(T one);
template<>
void theThing<MyClass_one>(MyClass_one one) {
cout << "im one" << endl;
}
template<>
void theThing<MyClass_two>(MyClass_two one) {
cout << "im two" << endl;
}
template<typename T, typename ... Ts>
void doSomething(T one, Ts...two) {
theThing(one);
}
这样,您就可以为要使用的每个类提供专门的东西。奖励,它不会针对theThing
不专门针对的类型进行编译。
- 如果编译的源代码是特定于它编译的硬件的,我们如何分发它
- 如何修复我的最大公约数代码?它适用于除零和零以外的所有数字
- 请找出我的代码中的错误,它在提交得到错误答案的同时仍然适用于我的所有测试用例
- 是否有一种 STL 算法可以最后找到,但它也适用于指针?
- C++函数,它将数组、谓词和运算符作为参数,并将运算符应用于满足谓词的数组元素
- 如果我决定输入 (1 2) 而它要求 x,为什么我的输出会出错,但如果我输入 (12) 工作正常
- 结构化绑定:当某些内容看起来像引用并且行为类似于引用,但它不是引用时
- 括号检查器完美地适用于单个测试用例,但对于所有测试用例,它给出了分段错误?
- 将 lua 脚本转换为等效于它的指令(操作码)
- 我是否也应该包括 string.h,即使它存在于头文件中
- 我需要转换一些代码,以便它适用于输入和输出文件文本
- 如何在 C++ 中安全地为 char *array 重新分配内存(它适用于自定义字符串类)
- 仅允许模板参数为某些类型并基于它决定操作
- 如何在另一个类函数中使用类,而不依赖于它在C++中的声明位置
- 为什么我的简单C++项目在我可以看到之前就终止于日食?我如何让它停止
- 在发出等待条件变量的信号后,线程何时获取锁?是什么决定了它
- 查找一个字符串(如果它存在于另一个字符串中)
- 试图理解得墨忒耳定律,因为它适用于我的代码
- 如何在C++中强制在另一个对象(依赖于它)中实例化一个对象
- c++ set size不对应于它的元素个数