我正在尝试为数组/指针创建一组重载模板,其中当编译器知道数组的大小时将使用一个模板,而当它不使用时将使用另一个模板:
template <typename T, size_t SZ>
void moo(T (&arr)[SZ])
{ ... }
template <typename T>
void moo(T *ptr)
{ ... }
问题是,当编译器知道数组的大小时,重载是不明确的,编译失败。
有没有办法解决歧义(可能是通过SFINAE)或者这是不可能的。
答案 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