Jak zapobiec niewspecjalizowanej instancji szablonu?

Mam szablon class (nazwij to Foo), który ma kilka specjalizacji. Chciałbym, aby kompilacja nie powiodła się, jeśli ktoś spróbuje użyć nieokreślonej wersji Foo.

Oto co właściwie mam:

template <typename Type>
class Foo
{
  Foo() { cannot_instantiate_an_unspecialized_Foo(); }

  // This method is NEVER defined to prevent linking.
  // Its name was chosen to provide a clear explanation why the compilation failed.
  void cannot_instantiate_an_unspecialized_Foo();
};

template <>
class Foo<int>
{    };

template <>
class Foo<double>
{    };

Tak, że:

int main()
{
  Foo<int> foo;
}

Działa podczas:

int main()
{
  Foo<char> foo;
}
Nie.

Oczywiście, łańcuch kompilatora skarży się tylko wtedy, gdy zachodzi proces łączenia. Ale czy jest sposób, aby to narzekać wcześniej ?

I can use boost.

Author: MSalters, 2011-08-15

3 answers

Po prostu nie Definiuj klasy:

template <typename Type>
class Foo;

template <>
class Foo<int> { };

int main(int argc, char *argv[]) 
{
    Foo<int> f; // Fine, Foo<int> exists
    Foo<char> fc; // Error, incomplete type
    return 0;
}
Dlaczego to działa? Po prostu dlatego, że nie ma żadnego ogólnego szablonu. Deklarowane, tak, ale nie zdefiniowane.
 46
Author: Seb Holzapfel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-15 10:56:28

Możesz po prostu nie definiować przypadku podstawowego:

template <typename> class Foo;             // no definition!

template <> class Foo<int> { /* ... */ };  // Foo<int> is OK
 24
Author: Kerrek SB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-15 10:46:32

Sztuczka dla C++0x (dostępna również z emulacją C++03 static_assert, ale Komunikat o błędzie niekoniecznie jest lepszy niż pozostawienie podstawowego szablonu niezdefiniowanego):

template<typename T>
struct dependent_false: std::false_type {};

template<typename Type>
struct Foo {
    static_assert( dependent_false<Type>::value
                 , "Only specializations of Foo may be used" );
};

Twierdzenie zostanie wywołane tylko wtedy, gdy Foo zostanie utworzona instancja z głównym szablonem. Użycie static_assert( false, ... ) wywołałoby twierdzenie cały czas.

 17
Author: Luc Danton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-15 11:00:05