我想知道模板(或者您可能推荐的任何其他工具)是否可能只从特定类型列表中获取类型(如枚举,但已有现有类型)。 更具体地说,如果我有3个类,A类,B类和C类,并且我喜欢能够将这三个类中的任何一个作为参数(但没有其他类比3)的函数,那么我该怎么办? 我应该使用模板(如果是这样我应该如何使用它),还是有其他工具供我使用?
答案 0 :(得分:5)
我想到的选项是SFINAE,static_assert或重载。什么选项最好取决于功能本身。
SFINAE方法
#include <type_traits>
template <typename T, typename std::enable_if<
std::is_same<A, T>::value ||
std::is_same<B, T>::value ||
std::is_same<C, T>::value, int>::type = 0>
void foo(T t) {
// ...
}
静态断言
template <typename T>
void foo(T t) {
static_assert(std::is_same<A, T>::value ||
std::is_same<A, T>::value ||
std::is_same<A, T>::value, "Must pass A, B or C");
// ...
}
重载
void foo(A a) {
// ...
}
void foo(B a) {
// ...
}
void foo(C a) {
// ...
}
答案 1 :(得分:2)
class
es?一般来说,最好保持接口开放并支持任何类型(当然,在合理范围内)。如果您确定要这样做,那么自定义类型特征和enable_if
可能是最佳途径。
#include <iostream>
#include <type_traits>
template <typename T>
struct is_my_special_type;
template <>
struct is_my_special_type<int> {
static const bool value = true;
};
template <>
struct is_my_special_type<long> {
static const bool value = true;
};
template <typename T, typename std::enable_if<is_my_special_type<T>::value, int>::type = 0>
void foo(T val) {
std::cout << val << '\n';
}
int main() {
foo(10);
foo(10l);
foo(10.0); // won't compile unless you comment this line out
return 0;
}
您可以通过my_special_type
的模板专精化添加类型。如果您愿意,也可以使用static_assert
代替enable_if
。
答案 2 :(得分:-1)
将模板参数限制为仅属于特定类型或满足特定要求的类型,是C++ Concepts的一部分。
概念是C ++语言的未来特性(可能在C ++ 20中的官方标准),已在TS(技术规范)中指定 - 使它们成为编译器可能的扩展,如果他们愿意的话
对于简短的介绍 - 这不是故意的,请注意:
What makes a good C++ concept? / Bjarne Stroustrup,CppCon 2016