如何使用模板类型专门化模板功能

时间:2014-04-02 11:41:29

标签: c++ templates partial-specialization

是否可以为模板类型专门化模板功能?我不知道我的术语是否正确,所以我将提供一个简单的样本,我想要实现的目标:

#include <vector>
#include <string>
#include <iostream>

template<typename T>
void f()
{
    std::cout << "generic" << std::endl;
}

template<>
void f<std::string>()
{
    std::cout << "string" << std::endl;
}

template<typename T>
void f<std::vector<T>>()
{
    std::cout << "vector" << std::endl;
}

int main()
{
    f<double>();
    f<std::string>();
    f<std::vector<int>>();

    return 0;
}

此代码无法编译。 VS2013给了我

  

错误C2995:'void f(void)':已经定义了函数模板

关于此功能:

template<typename T>
void f<std::vector<T>>()
{
    std::cout << "vector" << std::endl;
}

我怎样才能实现这种行为?拥有type f(void)签名非常重要。这段代码是否属于函数的部分特化(在C ++中是禁止的)?

2 个答案:

答案 0 :(得分:10)

您无法部分专门化模板功能,但您可以使用模板类。 因此,您可以将实现转发到专用类。 以下内容可能有所帮助:(https://ideone.com/2V39Ik

namespace details
{
    template <typename T>
    struct f_caller
    {
        static void f() { std::cout << "generic" << std::endl; }
    };

    template<>
    struct f_caller<std::string>
    {
        static void f() { std::cout << "string" << std::endl; }
    };

    template<typename T>
    struct f_caller<std::vector<T>>
    {
        static void f() { std::cout << "vector" << std::endl; }
    };
}

template<typename T>
void f()
{
    details::f_caller<T>::f();
}

答案 1 :(得分:3)

尽量与原始代码尽可能接近:

#include <vector>
#include <string>
#include <iostream>

template<typename T>
struct f {
    void operator()()
    {
        std::cout << "generic" << std::endl;
    }
};

template<>
struct f<std::string> {
    void operator()()
    {
        std::cout << "string" << std::endl;
    }
};

template<typename T>
struct f<std::vector<T> > {
    void operator()()
    {
        std::cout << "vector" << std::endl;
    }
};

int main()
{
    f<double>()();
    f<std::string>()();
    f<std::vector<int> >()();

    return 0;
}