数组衰减为指针和重载分辨率
array decay to pointer and overload resolution
我希望能够在重载分辨率中区分数组和指针:
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
}
到目前为止,我发现的最好的是使用对指针的引用而不是指针:
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 the array version
}
这不是完全相同的事情,我想知道是否存在更好的方法
当两个重载都可行时,您需要使第一个重载成为更糟糕的选择。 目前,它们在转换排名上是平局(两者都是"完全匹配"),然后由于首选非模板而打破了平局。
这应该会使转换排名变得更糟:
struct stg
{
struct cvt { const char* p; cvt(const char* p_p) : p(p_p) {} };
// matches const char*, but disfavored in overload ranking
stg(cvt c_str); // use c_str.p inside :( Or add an implicit conversion
template<int N>
stg(const char (&str) [N]);
};
您可以使用 SFINAE。这可能不是最好的方法,但它应该可以正常工作:
//thanks to dyp for further reduction
template<typename T, typename = typename std::enable_if<std::is_same<T, char>::value>::type>
string(const T * const &) {std::cout << "const char *n";}
template<std::size_t N> //credit to jrok for noticing the unnecessary SFINAE
string(const char(&)[N]) {std::cout << "const char(&)[" << N << "]n";}
这是一个活生生的例子。
可以检测到此问题的更通用版本,如下所示。
template <class T>
void func(T,
typename std::enable_if<std::is_pointer<T>::value, void>::type * = 0)
{
// catch ptr
}
template <class T, int N>
void func(T (&)[N])
{
//catch array
}
int main(void)
{
int arr[5];
char *b = 0;
func(arr); // catch array
func(b); // catch ptr
}
相关文章:
- C++ 重载分辨率和恒常性
- 模板和重载分辨率
- 为什么重载分辨率不选择模板函数的 std::vector 重载?
- 使用空大括号初始值设定项的重载分辨率:指针还是引用?
- 如何获取通过重载分辨率选择的函子签名
- 重载分辨率:是否首选直接转换运算符(由于复制省略)?
- 当参数不同时,重载分辨率不会选择模板
- 为什么下面的模板函数重载分辨率不明确
- 重载分辨率:调整 const/ref 是否不比用户定义的转换更好?
- 重载分辨率 C 样式字符串
- 具有引用限定符的模板方法的重载分辨率
- 具有自动功能的模板函数的重载分辨率
- 模板重载分辨率中的位字段
- 重载分辨率如何适用于 std::vector:<int>:insert
- 外部"C"和 "C++" 版本的 qsort()/bsearch() 上的重载分辨率
- 数组衰减为指针和重载分辨率
- 为什么重载分辨率不选择第一个函数?
- 从幻数到int或long的重载分辨率(范围为v3)
- 函数重载分辨率
- 具有多个函数和多个转换运算符的重载分辨率