为什么“literal’`鼓励在C参数类型匹配中朽烂到`const char *`?

为什么“literal’`鼓励在C参数类型匹配中朽烂到`const char *`?,第1张

概述我在C14中玩过重载 *** 作符,我试图匹配两种类型的参数:any-old-const-char *和a-string-literal. 也就是说,我试图看看我是否可以区分: const char * run_time; 和 "compile time" 我在下面写了代码,如图所示,当我尝试span>> “literal”它调用了const char *函数. 当我#if 0-out的const cha 我在C14中玩过重载 *** 作符,我试图匹配两种类型的参数:any-old-const-char *和a-string-literal.

也就是说,我试图看看我是否可以区分:

const char * run_time;

"compile time"

我在下面写了代码,如图所示,当我尝试span>> “literal”它调用了const char *函数.

当我#if 0-out的const char *版本,模板版本被调用就好了.

如果我更改模板版本以获取文字的rvalue-reference(&&)参数,则不会编译.

如果我添加一个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>autooperator>>(gsl::span<const char*,-1>& spn,const char (&literal)[N])    -> gsl::span<const char*,-1>&{    cout << "Got array: " << literal << endl;    return spn;}autooperator>>(gsl::span<const char*,const char *literal)    -> gsl::span<const char*,-1>&{    cout << "Got const-char*: " << literal << endl;    return spn;}#if 0#endifintmain(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++ --versionApple LLVM version 8.0.0 (clang-800.0.42.1)Target: x86_64-apple-darwin16.5.0Thread model: posixInstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
解决方法

Why is const char* preferred over const char (&)[N]?

其原因相当技术性.即使一个字符串字符串从const char [N]到const char *的衰减是一个转换,它属于“lvalue转换”类别,因此被[over.ics.rank] / 3认为是一样好根本没有转换.由于任何一个超载都需要“无转换”,所以非模板重载胜利.

Why is const char (&)[N] preferred over const char (&)[] (non-template)?

不可能将未知绑定数组的引用绑定到已知绑定的数组类型的值.相反,对未知绑定数组的引用只能绑定到本身是未知绑定数组的值.

Why is const char (&&)[N] unable to compile?

字符串字面值是一个左值,所以我不知道为什么你会期望这个工作.

Is there a “right way” to capture literal strings?

您可以使用一个帮助函数模板,使用转发引用捕获其参数,以便不破坏任何类型信息(const char *对const char [N])),然后使用模板专门化分派类型.你可能还想使用SFINAE来确保它被禁用,除了const char *或const char [N]之外的其他任何东西.

template <bool b>struct f_helper;template <>struct f_helper<true> {    voID do_it(const char*) {        puts("pointer");    }};template <>struct f_helper<false> {    template <std::size_t N>    voID do_it(const char (&)[N]) {        printf("array of length %zd\n",N);    }};template <class T,class = typename std::enable_if<std::is_same<char*,std::decay_t<T>>::value ||                                                   std::is_same<const char*,std::decay_t<T>>::value>::type>voID f(T&& s) {    f_helper<std::is_pointer<std::remove_reference_t<T>>::value>{}.do_it(s);}

Coliru链接:http://coliru.stacked-crooked.com/a/0e9681868d715e87

总结

以上是内存溢出为你收集整理的为什么“literal’`鼓励在C参数类型匹配中朽烂到`const char *`?全部内容,希望文章能够帮你解决为什么“literal’`鼓励在C参数类型匹配中朽烂到`const char *`?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/langs/1235707.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存