考虑以下C ++代码:
typedef std::string& mutable_string_ref;
const std::string str = "abc";
mutable_string_ref ref(str);
这显然会导致编译器错误,因为您无法创建对const字符串的可变引用。使用GCC 4.7.2,产生的错误是:
error: invalid initialization of reference of type ‘mutable_string_ref {aka std::basic_string<char>&}’ from expression of type ‘const string {aka const std::basic_string<char>}’
但是 ...为什么如果我们尝试同样的事情,只有我们将引用类型作为模板参数传递,突然间它似乎忽略了const -ness?
考虑:
template <class T>
T get()
{
const static std::string s = "abc";
return T(s);
}
int main()
{
std::string& s = get<std::string&>();
s = "blah"; // undefined behavior!!
}
上面的代码在GCC 4.7.2上编译得很好,没有任何警告。我不明白它为什么编译。似乎表达式T(s)
基本上被解释为C样式的强制转换,只是抛弃了const-ness。但为什么?我使用get
实例化了函数模板T = std::string&
,因此表达式return T(s)
应该无法编译,因为s
是const
。但它并没有失败。
Ideone链接:http://ideone.com/TAO5C6
这是编译器错误吗?或者这个编译是否有正当理由?
答案 0 :(得分:3)
你没有初始化,你是C风格的投射,它确实能够抛弃常数。
来自标准:
5.2.3显式类型转换(功能表示法)[expr.type.conv]
1 简单类型说明符(7.1.6.2)或typename-specifier(14.6)后跟带括号的expression-list,在给定表达式列表的情况下构造指定类型的值。如果表达式列表是单个表达式,则类型转换表达式与相应的强制转换表达式(5.4)等效(在定义中,如果在意义上定义)。
5.4显式类型转换(强制转换符号)
1 表达式(T)cast-expression的结果是T型。[...]