Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting to reference in a template seems to cast away const-ness

Tags:

c++

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?

like image 609
Siler Avatar asked Feb 23 '14 19:02

Siler


1 Answers

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. [...]

like image 85
Yam Marcovic Avatar answered Nov 20 '22 06:11

Yam Marcovic