【发布时间】:2017-05-02 07:10:33
【问题描述】:
我正在使用 c++14 中的重载运算符,我尝试匹配两种类型的参数:any-old-const-char* 和 a-string-literal。
也就是说,我正在尝试看看我是否可以区分:
const char * run_time;
和
"compile time"
我编写了下面的代码,如图所示,当我尝试span >> "literal" 时,它调用了const char* 函数。
当我#if 0-out the const char* 版本时,模板版本被调用就好了。
如果我将模板版本更改为采用literal 的右值引用 (&&) 参数,它不会编译。
如果我添加const char (&literal)[] 非模板版本,const char* 版本仍然是首选。去掉 const-char* 版本,首选模板版本。
你能解释一下吗?特别是:
- 为什么
const char*比const char (&)[N]更受欢迎? - 为什么
const char (&)[N]优于const char (&)[](非模板)? - 为什么
const char (&&)[N]无法编译? - 是否有“正确的方法”来捕获文字字符串?
谢谢。
#include <iostream>
using namespace std;
#include <gsl/gsl>
#include <type_name.h++>
template<unsigned N>
auto
operator>>(gsl::span<const char*,-1>& spn, const char (&literal)[N])
-> gsl::span<const char*, -1>&
{
cout << "Got array: " << literal << endl;
return spn;
}
auto
operator>>(gsl::span<const char*,-1>& spn, const char *literal)
-> gsl::span<const char*, -1>&
{
cout << "Got const-char*: " << literal << endl;
return spn;
}
#if 0
#endif
int
main(int argc, const char *argv[])
{
auto spn = gsl::span<const char*>(argv, argc);
cout << type_name<decltype(spn)>() << endl; // gsl::span<const char *, -1>
cout << type_name<decltype("literal")>() << endl; // char const (&)[8]
cout << type_name<decltype(("literal"))>() << endl; // char const (&)[8]
auto helpx = "literal";
cout << type_name<decltype(helpx)>() << endl; // const char *
spn >> "literal"; // Got const-char*: literal
return 0;
}
编辑:
如果它很重要,我正在编译:
c++ --std=c++14 -Iinclude -c -o main.o main.c++
而 c++ 说:
$ c++ --version
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin16.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
【问题讨论】:
-
我的猜测是选择它是因为它不是模板。非模板总是优先重载。
-
是的,非模板重载优于模板重载
-
另一方面,右值问题对我来说非常有趣,迫不及待想看到完整的答案......
-
@bolov: 除非其他方面同样好
-
IIRC
const char (&)[]无法绑定到const char [N]类型的值