C++ g++;:在临时对象的情况下,编译无法推断引用数组
我在下面的代码中遇到编译错误。我期待着即使是暂时的 对象可以绑定到常量引用。所以我想知道它应该是有效的代码。但是,g++给了我这个错误,而clang不会给这样的错误。有人告诉我发生这种情况的确切原因吗C++ g++;:在临时对象的情况下,编译无法推断引用数组,c++,templates,template-argument-deduction,C++,Templates,Template Argument Deduction,我在下面的代码中遇到编译错误。我期待着即使是暂时的 对象可以绑定到常量引用。所以我想知道它应该是有效的代码。但是,g++给了我这个错误,而clang不会给这样的错误。有人告诉我发生这种情况的确切原因吗 #include <iostream> struct TestClass { TestClass() : str() { strncpy(str, "hello", sizeof(str)); } char str[6];
#include <iostream>
struct TestClass
{
TestClass() : str()
{
strncpy(str, "hello", sizeof(str));
}
char str[6];
char (&getStr())[6]
{
return str;
}
};
template <typename T>
void printFunc(const T& str)
{
std::cout << str << std::endl;
}
int main()
{
TestClass obj;
printFunc(obj.str);
// printFunc(TestClass().str); // <- This line gives compilation error.
printFunc(TestClass().getStr());
return 0;
};
#包括
结构测试类
{
TestClass():str()
{
strncpy(str,“你好”,sizeof(str));
}
char-str[6];
char(&getStr())[6]
{
返回str;
}
};
样板
void printFunc(常量T和str)
{
STD::CUT< P>我假定您的GCC访问版本是“代码>测试类())。STR < /C>是一个RValk数组(C和C++语言中都是一个异乎寻常的东西)。在初始化时,当初始化是一个RValk时,有些东西不正确。显然,bug在后来的版本中被固定了。
同时,obj.str
和TestClass().getStr()
都是左值数组。它们由直接引用绑定的简单规则处理,因此不会出现问题
针对该评论:
如果将函数模板修改为
template <typename T> printFunc(const T str)
模板printFunc(const T str)
这种情况将发生巨大的变化。现在它不再是一个引用绑定问题。现在数组到指针的转换规则接管了它
在您的原始版本中,类型T
被推断为char[6]
,而在这个新的函数中,它被推断为char*
。当参数传递给函数时,您的数组类型完全丢失:它是一个被传递的指针。这完全消除了引用绑定的原始问题,并使代码无论数组的左值或右值如何编译
例如,您可以尝试在函数内部打印str的大小,并观察两个版本之间的差异。原始版本将以字节(6
)为单位打印数组大小,而新版本将以指针大小(4
,适用于ideone平台)为单位打印数组大小 < p>我假定您的GCC访问版本是“代码>测试类())。STR 是一个RValk数组(C和C++语言中都是一个异乎寻常的东西)。在初始化时,当初始化是一个RValk时,有些东西的执行错误。显然,bug在后来的版本中被固定了。
同时,obj.str
和TestClass().getStr()
都是左值数组。它们由直接引用绑定的简单规则处理,因此不会出现问题
针对该评论:
如果将函数模板修改为
template <typename T> printFunc(const T str)
模板printFunc(const T str)
这种情况将发生巨大的变化。现在它不再是一个引用绑定问题。现在数组到指针的转换规则接管了它
在您的原始版本中,类型T
被推断为char[6]
,而在这个新的函数中,它被推断为char*
。当参数传递给函数时,您的数组类型完全丢失:它是一个被传递的指针。这完全消除了引用绑定的原始问题,并使代码无论数组的左值或右值如何编译
例如,您可以尝试在函数内部打印str的大小,并观察两个版本之间的差异。原始版本将以字节(6
)为单位打印数组大小,而新版本将以指针大小(4
,适用于ideone平台)为单位打印数组大小.你确定吗?我使用了g++并且没有得到任何错误。为了将来的参考,不要使用html标签在你的帖子中放置代码,只需全部选中,然后点击{}
按钮。或者将其缩进4个空格(除了正常的代码缩进),这就是{}
按钮有。我无法用g++4.6.3重现您的错误。当然,在取消注释该行之后…确切的错误是什么?g++4.7.1没有给出任何错误。但是在旧的g++,错误被抛出。当我用void printFunc(const t&str)
替换void printFunc(const t str)时,错误消失
。你确定吗?我使用了g++并且没有得到任何错误。为了将来参考,不要使用html标记将代码放在帖子中,只需全部选中,然后点击{}
按钮。或者将其缩进4个空格(除了正常的代码缩进),这就是{}
按钮有。我无法用g++4.6.3重现您的错误。当然,在取消注释该行之后…确切的错误是什么?g++4.7.1没有给出任何错误。但是在旧的g++,错误被抛出。当我用void printFunc(const t&str)
替换void printFunc(const t str)时,错误消失
。当我将void printFunc(const T&str)
替换为void printFunc(const T str)
时,错误在ideone中消失。有什么解释吗?当我将void printFunc(const T&str)
替换为void printFunc(const T str)
时,错误在ideone中消失。有什么解释吗?