1

In order to force the execution of a template method at program start one can initialize a static member with a static method. Then the method is run at program start for every instantiation of the template class:

#include <cstdio>


template<typename t, t value>
struct dummy_user_t {};

template<int i>
struct my_struct_t
{
    static int s_value;

    // "use" s_value so it's initialized
    using value_user_t = dummy_user_t<const int&, s_value>;
    static int method()
    {
        printf("Hello %i!\n", i);
        return 0;
    }
};

// initialize s_value with method() to run it at program start
template<int i>
int my_struct_t<i>::s_value {my_struct_t<i>::method()};

// instantiate my_struct_t
template struct my_struct_t<6>;

int main()
{
    // nothing here
}

The output will be Hello 6!

This code compiles on all three major compilers but when you make s_value const it won't work in clang anymore (3.4 - 7.0) while still working in MSVC and GCC:

<source>:19:52: error: no member 'method' in 'my_struct_t<6>'; it has not yet been instantiated

const int my_struct_t<i>::s_value {my_struct_t<i>::method()};

                                               ^

<source>:10:51: note: in instantiation of static data member 'my_struct_t<6>::s_value' requested here

using value_user_t = dummy_user_t<const int&, s_value>;

                                              ^

<source>:21:17: note: in instantiation of template class 'my_struct_t<6>' requested here

template struct my_struct_t<6>;

            ^

<source>:11:16: note: not-yet-instantiated member is declared here

static int method()

           ^

1 error generated.

Try it out yourself:

With non const int: https://godbolt.org/z/m90bgS

With const int: https://godbolt.org/z/D3ywDq

What do you think? Is there any reason clang is rejecting this or is it a bug?

HenrikS
  • 402
  • 3
  • 13
  • Move the explicit instantiation above the usage of `my_struct_t::method()` and `clang` compiles like a champ: https://godbolt.org/z/758iFF – Swordfish Nov 15 '18 at 18:30
  • @Swordfish while that's true it defeats the purpose of being able to create new instantiation from anywhere in the code. – HenrikS Nov 15 '18 at 18:33
  • Another fix would be to move the type alias declaration beneath the definition of `my_struct_t::method()`. – Swordfish Nov 15 '18 at 19:35
  • Well, making s_value mutable isn't a big deal for my project. I was just curious which compiler is wrong. – HenrikS Nov 15 '18 at 19:37
  • Please re-read my last comment. You can have your `int const` with `clang` if you move `using value_user_t = dummy_user_t;` to after the definition of `method()`. – Swordfish Nov 15 '18 at 19:38
  • @Swordfish I don't think he is asking for a fix; he is asking for an explanation. Is clang right to reject the code or not? – ravnsgaard Nov 15 '18 at 20:00
  • Without looking up the standard i'd say `clang` has every right to complain. Order of initialization = order of declaration && at the time an initialized `s_value` is required the means to do so (`method()`) are not yet known. – Swordfish Nov 15 '18 at 20:25
  • But why does it work without const? – HenrikS Nov 15 '18 at 20:27

0 Answers0