这些模板可以明确无误

R S*_*hko 2 c++ arrays templates pointers

我正在尝试为数组/指针创建一组重载模板,其中当编译器知道数组的大小时将使用一个模板,而当它不使用时将使用另一个模板:

template <typename T, size_t SZ>
void moo(T (&arr)[SZ])
{ ... }

template <typename T>
void moo(T *ptr)
{ ... }
Run Code Online (Sandbox Code Playgroud)

问题是当编译器知道数组的大小时,重载是不明确的,编译失败.

有没有办法解决歧义(可能通过SFINAE)或这是不可能的.

Geo*_*che 5

这是可能的,因为可以确定模板参数是否为数组:

template<class T> struct is_array {
    enum { value = false }; 
};
template<class T, size_t N> struct is_array<T[N]> {
   enum { value = true }; 
};
template<class T> void f(T const&) { 
    std::cout << is_array<T>::value << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

结合使用enable_if,可以明确上述内容.例如,使用Boost.TypeTraits:

template <typename T, size_t SZ>
typename boost::enable_if<boost::is_array<T>, void>::type
f(T (&arr)[SZ]) {}
Run Code Online (Sandbox Code Playgroud)

但是根据参考资料,根本不需要SFINAE:

template<class T, size_t SZ> void f(T (&arr)[SZ]) {}
template<class T>            void f(T* const& t)  {}
Run Code Online (Sandbox Code Playgroud)

Johannes提出了另一种更适合当前情况的选择 - 使用SFINAE代替有问题的指针过载:

template <typename T, size_t SZ> void f(T (&arr)[SZ]) {}
template <typename T>
typename boost::enable_if<boost::is_pointer<T>, void>::type
f(T ptr) {}
Run Code Online (Sandbox Code Playgroud)