在模板中强制转换为引用似乎会抛弃恒定性
Casting to reference in a template seems to cast away const-ness
请考虑以下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>}’
但......为什么如果我们尝试同样的事情,只有我们将引用类型作为模板参数传递,突然它似乎忽略了恒定性?
考虑:
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式的演员阵容,只是抛弃了恒定性。 但是为什么? 我用T = std::string&
get
实例化了函数模板,所以表达式return T(s)
应该无法编译,因为s
是const
。 然而,它并没有失败。
Ideone link: http://ideone.com/TAO5C6
这是编译器错误吗? 还是有一些正当的理由编译?
你不是在初始化,你是C式的铸造,它确实有能力抛弃恒常性。
从标准:
5.2.3 显式类型转换(函数表示法) [expr.type.conv]
1简单类型说明符 (7.1.6.2) 或类型名说明符 (14.6) 后跟括号的表达式列表在给定表达式列表的情况下构造指定类型的值。如果表达式列表是单个表达式,则类型转换表达式等效(在定义性上,如果在含义上定义)与相应的强制转换表达式 (5.4) 等效。
5.4 显式类型转换(强制转换表示法)
1 表达式 (T) 转换表达式的结果为 T 类型。
相关文章:
- 将对象数组的引用传递给函数
- 什么时候在C++中返回常量引用是个好主意
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 指针类型类成员的动态强制转换的恒定性是什么?
- 为什么对引用的常量引用会失去其恒定性?
- 对指针和恒常性兼容性的引用
- 引用类型的数据成员提供有关恒常正确性"loophole"
- 运算符的要求<恒定性在标准::stable_sort
- 模板参数推导由于恒定性不一致而失败
- 为什么模板参数失去恒定性?
- 为什么普遍引用不保持其论点的恒定性
- 是否可以使用 SFINAE 检测类方法的恒定性?
- 在模板中强制转换为引用似乎会抛弃恒定性
- 在分配对象时保持恒定性
- 常量成员函数中模板成员的恒定性
- 变量的恒定性及其生存期
- 尊重恒定性,同时避免在堆上重新分配
- const_cast转换为左值引用不会消除恒常性
- 参考类成员的恒定性
- 当函数参数常量引用 T 时,为什么 T 的模板参数推导'skips'数组元素的恒定性?