有没有办法通过数组类型专门化函数模板?

Ser*_*sak 10 c++ templates c++11

比方说,我们需要一个函数模板,它应该根据类型返回一个整数:

template<typename T>
int get_type();
Run Code Online (Sandbox Code Playgroud)

此外,我们确实专门研究了几种类型:

template<>
int get_type<int>()
{
  return TYPE_INT;
}

// And so on for other types...
Run Code Online (Sandbox Code Playgroud)

这很有效,但不适用于数组类型。我可以执行以下操作:

template<>
int get_type<char[]>()
{
  return TYPE_STRING;
}
Run Code Online (Sandbox Code Playgroud)

编译器“同意”这一点,但链接器不同意。char[]例如,因为类型与char[5].

有没有办法实现这个没有函数参数的函数模板?即,我知道我们可以做这样的事情:

template<typename T>
int get_type(const T&);
Run Code Online (Sandbox Code Playgroud)

但是,实际上这里不需要(使用)函数参数。

编辑:

我使用 C++ 11。

Jar*_*d42 9

你不能部分特化模板函数(但你可以为模板类)

另一种方法是使用重载而不是专业化进行标签分派:

template <typename> struct Tag{};

constexpr int get_type(Tag<int>) { return TYPE_INT; }

template <std::size_t N>
constexpr int get_type(Tag<char[N]>) { return TYPE_STRING; }

template <typename T>
constexpr int get_type() { return get_type(Tag<T>{}); }
Run Code Online (Sandbox Code Playgroud)


Kon*_*lph 8

您需要部分专业化来解释可变数组长度,而 C++ 不允许部分专业化的函数模板。规范的解决方案是(部分)用(静态)成员(函数)专门化一个类模板,并从你的非专门化函数模板中分派给它:

namespace detail {
    template <typename T>
    struct get_type;

    template <>
    struct get_type<int> {
        static constexpr int value = TYPE_INT;
    };

    template <>
    struct get_type<char> {
        static constexpr int value = TYPE_CHAR;
    };

    template <typename T, std::size_t N>
    struct get_type<T[N]> {
        static constexpr int value = get_type<T>::value | TYPE_ARRAY;
    };

    template <std::size_t N>
    struct get_type<char[N]> {
        static constexpr int value = TYPE_STRING;
    };
} // namespace detail

template<typename T>
constexpr int get_type() {
    return detail::get_type<T>::value;
}
Run Code Online (Sandbox Code Playgroud)


For*_*veR 6

您不能部分地为具有大小的数组专门化函数。但是你可以通过课堂做到这一点。

template<typename T>
class type
{
    static int get_type();
};

template<>
struct type<int>
{
    static int get_type() { return 1; }
};

template<size_t SZ>
struct type<char[SZ]>
{
    static int get_type() { return 2; }
};

template<typename T>
int get_type() { return type<T>::get_type(); }

int main()
{
    std::cout << get_type<char[3]>() << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

例子