I have a templated class
(call it Foo
) which has several specializations. I would like the compilation to fail if someone tries to use an unspecialized version of Foo
.
Here is what I actually have:
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> { };
So that:
int main() { Foo<int> foo; }
Works while:
int main() { Foo<char> foo; }
Does not.
Obviously, the compiler chain only complains when the linking process takes place. But is there a way to make it complain before ?
I can use boost
.
When a function template is first called for each type, the compiler creates an instantiation. Each instantiation is a version of the templated function specialized for the type. This instantiation will be called every time the function is used for the type.
The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation to handle a specific set of template arguments is called a specialization.
Key differences between generics and C++ templates: Generics are generic until the types are substituted for them at runtime. Templates are specialized at compile time so they are not still parameterized types at runtime. The common language runtime specifically supports generics in MSIL.
" typename " is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.
Just don't define the class:
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; }
Why does this work? Simply because there isn't any generic template. Declared, yes, but not defined.
You can simply not define the base case:
template <typename> class Foo; // no definition! template <> class Foo<int> { /* ... */ }; // Foo<int> is OK
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With