C++ 如何确定模板函数中接收的类型是列表?

C++ 如何确定模板函数中接收的类型是列表?,c++,list,templates,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");

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

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;
}
模板
void printType()
{
if(typeid(T)=typeid(int))
{
printf(“类型为int。\r\n”);
}
else if(typeid(T)=typeid(std::string))
{
printf(“类型是字符串。\r\n”);
}
else if(typeid(T)=typeid(MyList))
{
printf(“类型是一个列表。\r\n”);
}
其他的
{
printf(“类型不受支持。\r\n”);
}
}
int main()
{
printType();
printType();
printType();
返回0;
}
对函数必须处理的类型的支持仅限于某些类型:int、string和list

我的问题是MyList的类型。 在我的示例代码中,该函数只处理int的列表,但我希望它处理的列表独立于它包含的元素类型(例如:
MyList
MyList
MyList
,等等)

这只不过是我的问题的一个尽可能小的表现


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

您可以专门化结构(不是函数)并省略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;
}

您可以专门化结构(不是函数)并省略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;
}

此操作不需要
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());
}
void printType_impl(int){
模板
void printType_impl(myList){}
void printType_impl(std::string){}
模板
void printType()
{
打印类型_impl(T());
}

如果您担心编译器不允许优化的默认构造的可能副作用,那么让
printType_impl
使用相应的指针,并像
printType(static_cast(nullptr))那样调用它取而代之。

不需要
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());
}
void printType_impl(int){
模板
void printType_impl(myList){}
void printType_impl(std::string){}
模板
void printType()
{
打印类型_impl(T());
}

如果您担心编译器不允许优化的默认构造的可能副作用,那么让
printType_impl
使用相应的指针,并像
printType(static_cast(nullptr))那样调用它代替。

使用
printType\u impl
获取指针并通过
printType\u impl((T*)0)调用是可以接受的。不需要构造任何东西。我会指望编译器对它进行优化。@jork:构造函数中的副作用呢@迪特尔说得很对。我认为这很少见,但我给出了答案。通过
printType\u impl
获取指针并通过
printType\u impl((T*)0)调用,这是可以接受的。不需要构造任何东西。我会指望编译器对它进行优化。@jork:构造函数中的副作用呢@迪特尔说得很对。我相信这是罕见的,但我给出了答案。因为我的真实世界有点复杂,我花了一段时间才掌握了模板专门化的窍门。它很好用。然而,我真的需要对整个类(或结构)进行专门化吗?例如,仅仅用类的一个给定方法不可能完成所有这些吗?@Rickforce没有办法在单个类或函数中专门化模板。我的实际情况稍微复杂一点,我花了一段时间才掌握模板专门化的窍门。它很好用。然而,我真的需要对整个类(或结构)进行专门化吗?例如,仅仅使用类的一个给定方法不可能完成所有这些吗?@Rickforce无法在单个类或函数中专门化模板