是否可以制作一个只能采用特定类型的模板?

时间:2018-04-22 20:52:49

标签: c++ oop c++11

我想知道模板(或者您可能推荐的任何其他工具)是否可能只从特定类型列表中获取类型(如枚举,但已有现有类型)。 更具体地说,如果我有3个类,A类,B类和C类,并且我喜欢能够将这三个类中的任何一个作为参数(但没有其他类比3)的函数,那么我该怎么办? 我应该使用模板(如果是这样我应该如何使用它),还是有其他工具供我使用?

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)

  1. 为什么你只想让它适用于三个class es?一般来说,最好保持接口开放并支持任何类型(当然,在合理范围内)。
  2. 如果您确定要这样做,那么自定义类型特征和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