Paolo Crosetto
Paolo Crosetto

Reputation: 1113

Isn't a struct with a reference data member a literal type?

, I don't understand the following behavior:

#include <memory>

template <int Index, typename Type>
struct position {
    using value_type = Type;

    template <typename TT>
    constexpr position( TT& val )
        : value{ val }
    {
    }

    static constexpr int index = Index;
    Type &               value;
};

int main()
{

    constexpr double d = 3.14;
    constexpr auto p1=position<3, const double>(d).value; // ok
    constexpr auto p2=position<3, const double>(d); // error
}

why position<3, double>(3.14).value can be a constant expression while position<3, double>( 3.14 ) is not?

I understand that the compiler would like the "position::value" data member to be a const reference, but why, isn't a reference a literal type?

Upvotes: 3

Views: 69

Answers (1)

cpplearner
cpplearner

Reputation: 15918

Isn't a struct with a reference data member a literal type?

Yes, such a struct is a literal type.

position<3, const double>(d) is not a constant expression because its member value does not refer to a permitted result of a constant expression, because the referent of value (i.e. d) is neither an object with static storage duration nor a function.

[expr.const]/6:

A constant expression is [...] or a prvalue core constant expression whose value satisfies the following constraints:

  • if the value is an object of class type, each non-static data member of reference type refers to an entity that is a permitted result of a constant expression,
  • [...]

An entity is a permitted result of a constant expression if it is an object with static storage duration [...], or it is a function.

Upvotes: 3

Related Questions