动机:
几乎是为了好玩,我试图编写一个函数重载,可以分辨参数是固定大小的数组还是指针.
double const d[] = {1.,2.,3.};
double a;
double const* p = &a;
f(d); // call array version
f(p); // call pointer version
Run Code Online (Sandbox Code Playgroud)
我发现这特别困难,因为众所周知的事实是数组比指针更快地衰减到指针.一种天真的方法就是写作
void f(double const* c){...}
template<size_t N> void f(double const(&a)[N]){...}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不起作用.因为在最好的情况下,编译器确定f(d)上面的数组调用是不明确的.
部分解决方案:
我尝试了很多东西,我能得到的最接近的是以下具体代码.另请注意,在此示例代码中我使用的是char代替double,但最后它非常相似.
首先,我必须使用SFINAE来禁用函数指针版本中的转换(从数组ref到ptr).其次,我不得不为所有可能的数组大小(手动)重载.
[可编码]
#include<type_traits> // for enable_if (use boost enable_if in C++98)
#include<iostream>
template<class Char, typename = typename std::enable_if<std::is_same<Char, char>::value>::type>
void f(Char const* dptr){std::cout << "ptr" << std::endl;} // preferred it seems
void f(char const (&darr)[0] ){std::cout << …Run Code Online (Sandbox Code Playgroud) 我希望能够在重载分辨率中区分数组和指针:
class string {
public:
string(const char* c_str);
template<int N>
string(const char (&str) [N]);
};
int main() {
const char* c_str = "foo";
string foo(c_str); // ok will call string(const char*)
string bar("bar"); // call string(const char*) instead of the array version
}
Run Code Online (Sandbox Code Playgroud)
到目前为止我发现的最好的是使用指针的引用而不是指针:
class string {
public:
string(const char*& c_str);
template<int N>
string(const char (&str) [N]);
};
int main() {
const char* c_str = "foo";
string foo(c_str); // ok will call string(const char*)
string bar("bar"); // ok, will call …Run Code Online (Sandbox Code Playgroud)