这些模板可以明确无误

时间:2010-05-23 00:49:28

标签: c++ arrays templates pointers

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

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

template <typename T>
void moo(T *ptr)
{ ... }

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

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

3 个答案:

答案 0 :(得分: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;
}

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

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

根据参考文献,根本不需要SFINAE:

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

约翰内斯提出了另一种适合当前情况的选择 - 使用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) {}

答案 1 :(得分:2)

可能是最简单的解决方案:

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

template <typename T>
inline void moo(T ptr) { __moo(ptr); }

template <typename T>
void __moo(T* ptr)
{ ... }

答案 2 :(得分:0)

您可以明确调用该函数:

int a[1] = {0}
moo<int,1>(a);

或者你可以在const上重载:

template<class T>
void moo(T const* p) { }

// ...
moo(a); // not const, array

int* p = 0;
moo(p); // pointer