我想编写一个区分数组和指针的函数。这是为了计算文字字符串的大小。我试过了:
template<typename Ty>
void f(const Ty* rhs) {
std::cout << __FUNCTION__ << rhs << std::endl;
}
template<typename Ty, size_t Dm>
void f(const Ty(&rhs)[Dm]) {
std::cout << __FUNCTION__ << rhs << std::endl;
}
int main(int, char*[]) {
const char arr0[] = "test2";
const char* ptr = "test3";
const char arr6[6] = "test4";
f("test1");
f(arr0);
f(ptr);
f(arr6);
return 0;
}
但是编译器(VS2013)告诉我这个调用是不明确的。任何提示?
提前致谢。
答案 0 :(得分:3)
不幸的是,电话不明确。
作为解决方法,您可以添加额外的图层:
template<typename Ty>
void f_pointer(const Ty* rhs) {
std::cout << __FUNCTION__ << rhs << std::endl;
}
template<typename Ty, size_t Dm>
void f_array(const Ty(&rhs)[Dm]) {
std::cout << __FUNCTION__ << rhs << std::endl;
}
template<typename T>
std::enable_if_t<std::is_array<T>::value>
f(const T&t)
{
f_array(t);
}
template<typename T>
std::enable_if_t<!std::is_array<T>::value>
f(const T&t)
{
f_pointer(t);
}
答案 1 :(得分:1)
Jarod42的替代方法(可行)是使用类模板专业化:
#include <iostream>
#include <type_traits>
template <typename T, bool is_array>
struct f_helper {
static void print_type (T& arg) {
std::cout << arg << " is an array\n";
}
};
template <typename T>
struct f_helper<T, false> {
static void print_type (T arg) {
std::cout << arg << " is not an array\n";
}
};
template <typename T>
void f (T& arg) {
f_helper<T, std::is_array<T>::value>::print_type (arg);
}
int main(int, char*[]) {
const char arr0[] = "test2";
const char* ptr = "test3";
const char arr6[6] = "test4";
f("test1");
f(arr0);
f(ptr);
f(arr6);
return 0;
}
答案 2 :(得分:0)
在函数模板的第二个重载中更改对指针的引用:
template<typename T, size_t S> void f(T(&)[S]){
cout << "array with size " << S << "\n";
}
template <typename T> void f(T*&) {
cout << "pointer \n";
}
答案 3 :(得分:-3)
我不相信你可以尝试按照自己的方式尝试。以下陈述评估同样的事情:
int* var
int var[]
这完全是语法糖的问题。此外,在函数头上向数组添加大小只有警告用户预期的数组大小的好处。因此,这两者也是等价的(就编译器而言):
void f(int* v)
void f(int v[8])