Как специализировать шаблонные функции с типами шаблонов

Можно ли специализировать функцию шаблона для типов шаблонов? Я не знаю, правильна ли моя терминология, поэтому приведу простой пример того, чего я хочу достичь:

#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 ответа

Решение

Вы не можете частично специализировать шаблонную функцию, но вы можете сделать это для класса шаблона. Таким образом, вы можете переслать вашу реализацию в выделенный класс. Может помочь следующее: ( 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();
}

Попытка быть как можно ближе к исходному коду:

#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;
}
Другие вопросы по тегам