Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ g++;将返回的字符串文字视为常量字符指针,而不是常量字符数组_C++_G++_String Literals - Fatal编程技术网

C++ g++;将返回的字符串文字视为常量字符指针,而不是常量字符数组

C++ g++;将返回的字符串文字视为常量字符指针,而不是常量字符数组,c++,g++,string-literals,C++,G++,String Literals,当从一个函数返回字符串文本时,我看到一些奇怪的行为,该函数应该使用g++(版本4.7.3)执行隐式转换。有人能解释为什么会出现以下代码: #include <stdio.h> class Test { public: template <unsigned int N> Test(const char (&foo)[N]) { printf("Template const char array constructor\n"); } T

当从一个函数返回字符串文本时,我看到一些奇怪的行为,该函数应该使用g++(版本4.7.3)执行隐式转换。有人能解释为什么会出现以下代码:

#include <stdio.h>

class Test
{
public:
  template <unsigned int N>
  Test(const char (&foo)[N])
  {
    printf("Template const char array constructor\n");
  }

  Test(char* foo)
  {
    printf("char* constructor\n");
  }
};

Test fn()
{
  return "foo";
}

int main()
{
  Test t("bar");
  Test u = fn();

  return 0;
}
关于g++?令人惊讶的是,当从fn()生成返回值时,char*构造函数优先于const char数组构造函数。诚然,这里有一个警告,“不推荐将字符串常量转换为'char*'”

更令人惊讶的是,如果删除char*构造函数,那么代码就不会用g++编译


它使用CLAN(模板构造函数使用了两个时间),正如我所预期的那样,这使得我认为这是一个编译器错误,但可能只是C++规范中一个奇怪的角落——有人能确认吗?

< P>这似乎是一个影响GCC的几个版本的bug,它已经被一次又一次的报告了。最近一次是在大约一个月前,与最新版本4.8.2相比。请参见

如果您想要一个可重用的C++03解决方案(即,您不必关心返回类型是什么,只要它是可从字符数组构造的),则必须使用某种字符数组包装器

template <size_t N>
struct char_array_ref
{
    typedef const char (&ref_type)[N];
    ref_type ref;

    template <typename T>
    operator T() const
    {
        return T(ref);
    }
};

template <size_t N>
char_array_ref<N> stupid_gxx_use_array_reference(const char (&chars)[N])
{
    return char_array_ref<N> { chars };
}


Test fn()
{
  return stupid_gxx_use_array_reference("foo");
}
模板
结构字符数组引用
{
typedef const char(&ref_type)[N];
ref_类型ref;
模板
运算符T()常量
{
返回T(ref);
}
};
模板
字符数组引用愚蠢的字符数组引用(常量字符和字符)[N])
{
返回char_数组_ref{chars};
}
测试fn()
{
返回愚蠢的_gxx_使用_数组_引用(“foo”);
}
正则表达式也应该很容易在您的代码库中传播


显然,在您的代码中,您可以将
愚蠢的\u gxx\u使用\u数组\u引用
更改为不太冗长的内容。

您的编译c++11,不是吗?@Paranaix我看到GCC 4.8在c++11模式下出现此问题,因此即使OP没有,这也不是问题。字符串文字在这里并不特殊,除了不推荐的到
char*
的转换之外,它的行为方式也与其他数组相同:
const char foo[4]={};返回foo因“错误:无法将”(const char*)(&foo)从“const char*”转换为“Test”而失败。这同样适用于函数引用:它们被转换为指针,并且任何接受引用的构造函数都不可用:
struct S{S(S(&)();};clang接受sf(){return f;}
,但gcc报告“错误:无法将'f'从'S(*)(')转换为'S'”。解决方法可能是
返回S(f),或者在您的示例中,
返回测试(“foo”)
@Gwiazdorr您的意思是“如果”,而不是“因为”,当然?+1解决方法是使用显式转换而不是隐式转换,即
返回测试(“foo”)
。到今天(略有不同但可能相关:)这一点仍然有效
template <size_t N>
struct char_array_ref
{
    typedef const char (&ref_type)[N];
    ref_type ref;

    template <typename T>
    operator T() const
    {
        return T(ref);
    }
};

template <size_t N>
char_array_ref<N> stupid_gxx_use_array_reference(const char (&chars)[N])
{
    return char_array_ref<N> { chars };
}


Test fn()
{
  return stupid_gxx_use_array_reference("foo");
}