如何确定模板化函数中接收的类型是否为列表?

时间:2014-02-26 17:34:40

标签: c++ list templates

假设我有一个模板化函数,只打印它在调用中收到的类型。

template<typename T>
void printType()
{
    if (typeid(T) == typeid(int))
    {
        printf("Type is int.\r\n");
    }
    else if (typeid(T) == typeid(std::string))
    {
        printf("Type is string.\r\n");
    }
    else if (typeid(T) == typeid(MyList<int>))
    {
        printf("Type is a list.\r\n");
    }
    else
    {
        printf("Type is not supported.\r\n");
    }
}

int main()
{
    printType<int>();
    printType<std::string>();
    printType<MyList<int>>();
    return 0;
}

对函数必须处理的类型的支持仅限于某些类型:int,string和list。

我的问题是MyList类型。 在我的示例代码中,该函数只处理整数列表,但我想让它处理一个独立于其包含的元素类型的列表(例如:MyList<double>MyList<std::string>,{{1}等等......)。

这只是我的问题的最小可能表现。

如何检测到函数调用提供的类型是MyList,而不管它包含哪个类型元素?

2 个答案:

答案 0 :(得分:3)

这不需要typeid。只需使用类型T调度到不同的重载:

void printType_impl(int) {}

template<typename T>
void printType_impl(myList<T>) {}

void printType_impl(std::string) {}

template<typename T>
void printType()
{
    printType_impl(T());
}

如果您担心默认构造的可能副作用,不允许编译器进行优化,那么让printType_impl取代相应的指针并改为调用printType( static_cast<T*>(nullptr) );

答案 1 :(得分:2)

您可能会专门化一个struct(而不是一个函数)并省略typeid:

#include <cstdio>
#include <string>

template <typename T>
struct MyList {};

namespace PrintType {

    template <typename T>
    struct Implementation {
        static void apply() {
            printf("Type is not supported.\r\n");
        }
    };

    template <>
    struct Implementation<int> {
        static void apply() {
            printf("Type is int.\r\n");
        }
    };

    // And more ...

    template <typename T>
    struct Implementation< MyList<T> > {
        static void apply() {
            printf("Type is a list.\r\n");
        }
    };
}

template <typename T>
void printType() {
    PrintType::Implementation<T>::apply();
}

int main()
{
    printType<int>();
    printType<std::string>();
    printType<MyList<int>>();
    return 0;
}

输出:

Type is int.
Type is not supported.
Type is a list.