Чтобы принудительно запустить шаблонный метод при запуске программы, можно инициализировать статический элемент статическим методом. Затем метод запускается при запуске программы для каждого экземпляра класса шаблона:
#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
}
Выход будет Hello 6!
Этот код компилируется на всех трех основных компиляторах, но когда вы делаете s_value const, он больше не будет работать в clang (3.4-7.0), все еще работая в MSVC и 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.
Попробуйте сами:
С неконстантным целым: https://godbolt.org/z/m90bgS
С const int: https://godbolt.org/z/D3ywDq
Что вы думаете? Есть ли какая-то причина, по которой кланг отвергает это или это ошибка?