Хорошо, поэтому, если вы форсируете создание экземпляров всех методов, используя явное создание экземпляров, вы не можете избежать каких-либо трюков времени компиляции, чтобы предотвратить создание экземпляров методов, вызывающих сбой, таких как enable_if
. Было бы достаточно легко перенести ошибку во время выполнения, но это нежелательно.
Я думаю, что лучшее, что вы можете сделать, это переместить ошибку во время компоновки, что статически гарантирует, что программа не содержит пути кода, который потенциально может вызвать запрещенную функцию, но сообщения об ошибках не будут очень полезны для любой, кто не знает об ограничении, которое вы налагаете. В любом случае, решение состоит в том, чтобы объявить специализацию запрещенных функций-членов, но не определить их:
template<typename T>
struct Foo {
void bar() {
std::cout << "bar\n";
}
void baz() {
std:: cout << "baz\n";
}
};
template<> void Foo<int>::baz(); // use of Foo<int>::baz() will resolve to this specialization, and linking will fail
template struct Foo<int>;
template struct Foo<char>;
int main() {
Foo<int> f;
f.bar();
// f.baz(); // uncommenting this line results in an ugly link time error
Foo<char> b;
b.bar();
b.baz(); // works with Foo<char>
}
Статические утверждения больше не помогают выдавать хорошие сообщения об ошибках, когда в клиентском коде допущена ошибка, но вы можете оставить их, потому что они сработают, если вы забудете указать специализацию.