У нас есть сложные шаблонные классы, которые имеют некоторые методы, которые не будут работать с определенными политиками или типами. Поэтому, когда мы обнаруживаем эти типы (во время компиляции, используя type-traits), мы запускаем статическое утверждение с красивым сообщением.
Сейчас мы также делаем много ручного инстанцирования шаблонов. Отчасти это делается для того, чтобы заставить компилятор проверять синтаксис методов. Это также сокращает время компиляции для пользователя библиотеки. Проблема в том, что статические утверждения всегда срабатывают, и, следовательно, мы не можем вручную инстанцировать данный класс шаблона.
Есть ли обходной путь для этого?
EDIT: Чтобы было понятнее, вот пример (явное инстанцирование в этом случае будет неудачным на someFunc1():
// header
template <typename T>
class someClass
{
void someFunc() {}
void someFunc1() { static_assert(false, assertion_failed); }
};
// source
template someClass<int>; // Explicit instantiation
EDIT2: Вот еще один пример. На этот раз вы можете скомпилировать его, чтобы понять, что я имею в виду. Сначала скомпилируйте сразу. Код должен скомпилироваться. Затем Uncomment [2] и статическое утверждение должно сработать. Теперь откомментируйте [2] и откомментируйте [1]. Статическое утверждение сработает, потому что вы явно инстанцируете шаблон. Я хочу избежать удаления явного инстанцирования из-за преимуществ, которые оно дает (о преимуществах см. выше).
namespace Loki
{
template<int> struct CompileTimeError;
template<> struct CompileTimeError<true> {};
}
#define LOKI_STATIC_CHECK(expr, msg) \
{ Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; }
template <typename T>
class foo
{
public:
void func() {}
void func1() { LOKI_STATIC_CHECK(sizeof(T) == 4, Assertion_error); }
};
template foo<int>;
//template foo<double>; // [1]
int main()
{
foo<int> a;
a.func1();
foo<double> b;
//b.func1(); //[2]
return 0;
}