Automatic + static constant initialization in a class with metaprogramming

Consider the following simplified metaprogrammable template that implements the Angle class, which internally stores a reduced value modulo 360 degrees.

 #include <iostream> #include <typeinfo> template<int N, int D> struct Modulus { static auto const value = N % D; }; template<int N> struct Angle { static auto const value = Modulus<N, 360>::value; // ERROR //static int const value = Modulus<N, 360>::value; // OK //static auto const value = N % 360; // OK typedef Angle<value> type; }; int main() { std::cout << typeid(Angle<30>::type).name() << "\n"; std::cout << typeid(Angle<390>::type).name() << "\n"; return 0; } 

Conclusion on Ideone

With Visual C ++ 2010 Express, I can do static auto const = Modulus<N, 360>::value , but with MinGW gcc 4.7.2 ( Nuwen distro ) or Ideone (gcc 4.5.1) I must either explicitly designate the type as static int const value = Modulus<N, 360>::value , or I need to use auto with a full modular expression as static auto const value = N % 360; .

Question: Which compiler is correct in accordance with the new C ++ 11 standard?

+6
source share
1 answer

The code is valid. Visual C ++ has the right to accept it, and gcc rejects it incorrectly (for completeness, Clang 3.1 also accepts code). The specification states that (C ++ 11 7.1.6.4 [dcl.spec.auto] / 4):

An auto type auto can also be used ... when declaring a static data item using the brace-or-equal-initializer attribute that appears in the class definition item specification.

Your value is a static data member. It has an peer-to-peer-initializer element (that is, part of the declaration = Modulus<N, 360>::value ), and the initializer appears inside the member specification of the class definition (that is, what mortals can call the "built-in initializer ").

+1
source

Source: https://habr.com/ru/post/927433/


All Articles