Reputation: 1113
, 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
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.
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