有没有一种方法可以将模板函数中允许的类型列入白名单?

时间:2019-09-10 18:30:00

标签: c++

我有一个模板功能,我只想使用特定的类型列表。

 template <class T> void foo(const T f) {/*do stuff with f*/}

 int main() {
        string A= "Hello world";
        char B[10] = "Hello world";
        Int C = 69;

        foo(A); //should work here
        foo(B); //and here
        foo(C); //but it should give an error here, preferably while it is compiling

       return 0;
 }

如果我用char []或字符串调用它,我希望它可以工作,但是当我尝试用INT类型调用它时,给出一个错误(可能是在编译时,但在运行时也起作用)。 / p>

3 个答案:

答案 0 :(得分:13)

对于您的特殊情况,我将重载函数foo而不是使用模板。这样可以确保您只能具有这两种类型之一,特别是对于这两种类型,重载非常简单:

void foo(const char* s) {
    // do work with s
}

void foo(const std::string& s) {
    foo(s.c_str()); // use the other overload for const char*
}

答案 1 :(得分:8)

SFINAE可能会帮助:

template <class T, std::enable_if_t<!std::is_same<int, T>::value, int> = 0>
void foo(const T f) {/*do stuff with f*/}

template <class T,
          std::enable_if_t<std::is_same<std::string, T>::value
                           || std::is_same<const char*, T>::value, int> = 0>
void foo(const T f) {/*do stuff with f*/}

根据您的需要调整条件。

static_assert

template <class T>
void foo(const T f) {
    static_assert(std::is_same<std::string, T>::value
                  || std::is_same<const char*, T>::value, "Incorrect type");
    /*do stuff with f*/
}

答案 2 :(得分:5)

对于这种特殊情况,最简单的方法是仅使用C ++ 17中的std::string_view。不仅接受std::string或char数组,而且接受char*加上大小,以及任何提供operator string_view()的内容。

那会给你

void foo(std::string_view sv) 
{
    //do stuff with sv
}

如果您是一般性的询问,则可以重载该功能,或者使用SFINAE之类的方式

template <class T, std::enable_if_t<std::is_same_v<T, some_type> ||
                                    std::is_same_v<T, some_other_type> ||
                                    std::is_same_v<T, even_more>, bool> = true> 
void foo(const T f) {/*do stuff with f*/}