Consider the following C++ code:
typedef std::string& mutable_string_ref;
const std::string str = "abc";
mutable_string_ref ref(str);
This obviously results in a compiler error, because you cannot create a mutable reference to a const string. With GCC 4.7.2, the error this produces is:
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>}’
BUT... why is it that if we try the same thing, only we pass the reference type as a template parameter, suddenly it seems to ignore the const-ness?
Consider:
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!!
}
The above code compiles fine on GCC 4.7.2, with no warnings. I don't understand why it compiles. It seems the expression T(s)
is basically being interpreted as a C-style cast that just casts away const-ness. But why? I instantiated the function template get
with T = std::string&
, so the expression return T(s)
should fail to compile because s
is const
. Yet it doesn't fail.
Ideone link: http://ideone.com/TAO5C6
Is this a compiler bug? Or is there some valid reason this compiles?
You're not initializing, you're C-style casting, which indeed has the ability to cast away constness.
From the standard:
5.2.3 Explicit type conversion (functional notation) [expr.type.conv]
1 A simple-type-specifier (7.1.6.2) or typename-specifier (14.6) followed by a parenthesized expression-list constructs a value of the specified type given the expression list. If the expression list is a single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression (5.4).
5.4 Explicit type conversion (cast notation)
1 The result of the expression (T) cast-expression is of type T. [...]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With