template<>
class A{
//some class data
};
I have seen this kind of code many times.
what is the use of template<> in the above code?
And what are the cases where we need mandate the use of it?
template<> tells the compiler that a template specialization follows, specifically a full specialization. Normally, class A would have to look something like this:
template<class T>
class A{
// general implementation
};
template<>
class A<int>{
// special implementation for ints
};
Now, whenever A<int> is used, the specialized version is used. You can also use it to specialize functions:
template<class T>
void foo(T t){
// general
}
template<>
void foo<int>(int i){
// for ints
}
// doesn't actually need the <int>
// as the specialization can be deduced from the parameter type
template<>
void foo(int i){
// also valid
}
Normally though, you shouldn't specialize functions, as simple overloads are generally considered superior:
void foo(int i){
// better
}
And now, to make it overkill, the following is a partial specialization:
template<class T1, class T2>
class B{
};
template<class T1>
class B<T1, int>{
};
Works the same way as a full specialization, just that the specialized version is used whenever the second template parameter is an int (e.g., B<bool,int>, B<YourType,int>, etc).
template<> introduces a total specialization of a template. Your example by itself isn't actually valid; you need a more detailed scenario before it becomes useful:
template <typename T>
class A
{
// body for the general case
};
template <>
class A<bool>
{
// body that only applies for T = bool
};
int main()
{
// ...
A<int> ai; // uses the first class definition
A<bool> ab; // uses the second class definition
// ...
}
It looks strange because it's a special case of a more powerful feature, which is called "partial specialization."
Doesn't look right. Now, you might have instead written:
template<>
class A<foo> {
// some stuff
};
... which would be a template specialisation for type foo.
Related
Let's suppose to have a templateclass Foo:
template <typename T>
class Foo {
void foo();
};
I have another template class Bar (independent from the first one):
template <int N>
class Bar {};
Let's say, I want to specialise the foo() method for whatever Bar class.
I'd wrongly write:
template <>
template <int N>
void Foo<Bar<N> >::foo() { /* ... */ }
The compiler blames me for because the type is not complete:
error: invalid use of incomplete type 'class Foo<Bar<N> >'
void Foo<Bar<N> >::foo() { }
Code
I am using C++98, but I'd like to know if there exist different solutions in C++11.
Note
I could solve the problem specialising the entire class Foo for a generic Bar, but after I should have to define all methods.
Example Code
That's not what I want, I am looking for (if exists) more elegant solution (both C++98 and C++11) which allows me to specialise and implement only a single class method.
EDIT:
The question on SO does not explain how to specialise with a template argument. Indeed, my question shows how the compiler complains about that.
For C++11 you can SFINAE enable/disable (using std::enable_if) two differents versions of foo() inside a not specialized Foo class.
In C++98 you don't have std::enable_if but you can simulate it (give me some minutes and I try to propose an example). Sorry: my idea doesn't works because this method require the use of default template arguments for methods that is a C++11 innovation.
Another way is define a template base class for Foo(), say FooBase, insert foo() (and only foo()) in FooBase and specialize FooBase.
Another way, that works also with C++98, can be tag dispatching: you can define an unique foo(), with zero parameter, that call another foo(), with a parameter that is determined by T.
The following is a full (C++98 compilable) example
#include <iostream>
struct barWay {};
struct noBarWay {};
template <int>
struct Bar
{ };
template <typename>
struct selectType
{ typedef noBarWay type; };
template <int N>
struct selectType< Bar<N> >
{ typedef barWay type; };
template <typename T>
struct Foo
{
void foo (noBarWay const &)
{ std::cout << "not Bar version" << std::endl; }
void foo (barWay const &)
{ std::cout << "Bar version" << std::endl; }
void foo ()
{ foo(typename selectType<T>::type()); }
};
int main ()
{
Foo<int> fi;
Foo< Bar<42> > fb;
fi.foo();
fb.foo();
}
if a common base is not desirable, yet another way could be giving foo() a customization point, like a trait for example:
template <typename T>
struct foo_traits;
template <typename T>
struct Foo {
void foo(){ foo_traits<T>::foo_cp(*this); }
};
template <typename T>
struct foo_traits{ static void foo_cp(T&){/*default*/} };
template <int N>
class Bar {};
template <int N>
struct foo_traits<Bar<N>>{ static void foo_cp(Foo<Bar<N>>&){/*spec*/} };
such trait could also be an implementation detail friend, if its only purpose is to internally provide a foo() specialization for Bar's.
If you cannot specialize foo, define it so that it delegates the call to an internal foo-implementation class. Then specialize that class.
Something like this should compile in C++98 and it doesn't differ much from your original code:
template <typename T>
class Foo {
template<typename>
struct FooImpl;
public:
void foo() { FooImpl<T>()(); }
};
template <int N>
class Bar {};
template <typename T>
template <int N>
struct Foo<T>::FooImpl< Bar<N> > {
void operator()() { /* ... */ }
};
int main() {
Foo< Bar<0> > fb;
fb.foo();
Foo<int> fi;
//fi.foo();
}
The last line doesn't compile as expected (at least I got it was the expected result, just define the function call operator for FooImpl otherwise).
This way you can define selectively the specializations for which you want foo to work. In all the other cases, an attempt at using foo will result in a compilation error.
I'd like to know if there exist different solutions in C++11.
This is a classic use case for tagged dispatch, of which max66 already suggested. The approach, and even syntax, are basically the same in C++98 and C++11.
Here's a bit of a cleaner implementation than max66's, I believe (running on godbolt):
template <class T>
class Foo {
template <class>
struct tag{};
template<class U>
void foo_helper(tag<U>){std::cout << "default\n";}
void foo_helper(tag<Bar<3> >){std::cout << "specialization for Bar<3>\n";}
public:
void foo(){return foo_helper(tag<T>());}
};
The principle is the same; a client function accepting no arguments calls a helper function that constructs an empty type based on the T argument. Then normal overloading takes care of the rest.
Only here I use a templated catch-all method.
In C++11 the syntax would only change slightly; We could say tag<Bar<3>> instead of tag<Bar<3> > because new parsing rules allow the chevron for nested templates.
We could also make the tag and the templated foo_helper catch-all into variadic templates to be a little more generic:
template <class T>
class Foo {
template <class...>
struct tag{};
template<class... U>
void foo_helper(tag<U...>){std::cout << "default\n";}
void foo_helper(tag<Bar<3>>){std::cout << "specialization for Bar<3>\n";}
public:
void foo(){return foo_helper(tag<T>{});}
};
Things actually start getting pretty interesting in C++17 with the introduction of constexpr if that allows us to write what looks like normal branching logic based on T (Live Demo):
template <class T>
class Foo {
public:
void foo(){
if constexpr (std::is_same_v<T, Bar<3>>){std::cout << "Specialization for Bar<3>\n";}
else std::cout << "default\n";
}
};
As you can see, all the tag stuff goes away in favor of using a simple if statement.
We take advantage of type_traits introduced in C++11 to check the type of T against our desired type. Something like this wouldn't necessarily work previously because all branches needed to be compiled. In C++17, only the branch that is selected (at compile-time) is compiled.
Note that you could emulate this behavior as early as C++98 by using typeid (godbolt demo):
void foo(){
if (typeid(T) == typeid(Bar<3>)){std::cout << "Specialization for Bar<3>\n";}
else std::cout << "default\n";
}
However, the typeid approach is a poor choice for 2 reasons:
It's a run time check (slow) for information we know at compile-time
It's brittle because all branches must compile for all template instantiations, whereas in C++17 if constexpr only compiles the branch that is selected.
I have a templatized class like so :
template<typename T>
class A
{
protected:
std::vector<T> myVector;
public:
/*
constructors + a bunch of member functions here
*/
}
I would like to add just ONE member function that would work only for 1 given type of T. Is it possible to do that at all without having to specialize the class and reimplement all the other already existing methods?
Thanks
The simplest and cleanest solution is to use a static_assert() in the body of a method, rejecting other types than the selected one (in the below example only integers are accepted):
#include <type_traits>
#include <vector>
template <typename T>
class A
{
public:
void onlyForInts(T t)
{
static_assert(std::is_same<T, int>::value, "Works only with ints!");
}
protected:
std::vector<T> myVector;
};
int main()
{
A<int> i;
i.onlyForInts(1); // works !
A<float> f;
//f.onlyForInts(3.14f); // does not compile !
}
OK CASE DEMO
NOK CASE DEMO
This utilizes the fact that a compiler instantiates a member function of a class template only when one is actually used (not when the class template is instantiated itself). And with the above solution, when a compiler tries to do so, it fails due to the execution of a static_assert.
C++ Standard Reference:
§ 14.7.1 Implicit instantiation [temp.inst]
Unless a function template specialization has been explicitly instantiated or explicitly specialized, the function template specialization is implicitly instantiated when the specialization is referenced in a context that requires a function definition to exist. Unless a call is to a function template explicit specialization or to a member function of an explicitly specialized class template, a default argument for a function template or a member function of a class template is implicitly instantiated when the function is called in a context that requires the value of the default argument.
[ Example:
template<class T> struct Z {
void f();
void g();
};
void h() {
Z<int> a; // instantiation of class Z<int> required
Z<char>* p; // instantiation of class Z<char> not required
Z<double>* q; // instantiation of class Z<double> not required
a.f(); // instantiation of Z<int>::f() required
p->g(); // instantiation of class Z<char> required, and
// instantiation of Z<char>::g() required
}
Nothing in this example requires class Z<double>, Z<int>::g(), or Z<char>::f() to be implicitly
instantiated. — end example ]
Yes, it's possible in C++03 with CRTP (Curiously recurring template pattern):
#include <numeric>
#include <vector>
template<typename Derived, typename T>
struct Base
{
};
template<typename Derived>
struct Base<Derived, int>
{
int Sum() const
{
return std::accumulate(static_cast<Derived const*>(this)->myVector.begin(), static_cast<Derived const*>(this)->myVector.end(), int());
}
};
template<typename T>
class A : public Base<A<T>, T>
{
friend class Base<A<T>, T>;
protected:
std::vector<T> myVector;
public:
/*
constructors + a bunch of member functions here
*/
};
int main()
{
A<int> Foo;
Foo.Sum();
}
As an alternative solution, which works also in plain C++03 (as opposed to static_assert or enable_if solutions), you may add extra defaulted template argument which will let you have both
specialized and unspecialized version of class. Then you can inherit your specialized version from the unspecialized one.
Here is a sample snippet:
#include <vector>
template<typename T, bool unspecialized = false>
class A
{
protected:
std::vector<T> myVector;
public:
void setVec(const std::vector<T>& vec) { myVector = vec; }
/*
constructors + a bunch of member functions here
*/
};
template<>
class A<int, false> : public A<int, true>
{
public:
int onlyForInt() {
return 25;
}
};
int main() {
// your code goes here
std::vector<int> vec;
A<int> a;
a.setVec(vec);
a.onlyForInt();
return 0;
}
The drawbacks of this solution is the need to add constructor forwarders, if class
has non-trivial constructors.
The static_assert technique by #PiotrS. works nicely. But it's also nice to know that you can specialize a single member function without code duplication. Just give the generic onlyForInts() an empty no-op implementation, and specialize it out-of-class for int
#include <vector>
template <typename T>
class A
{
public:
void onlyForInts(T t)
{
// no-op
}
protected:
std::vector<T> myVector;
};
template<>
void A<int>::onlyForInts(int t)
{
// works
}
int main()
{
A<int> i;
i.onlyForInts(1); // works !
A<float> f;
f.onlyForInts(3.14f); // compiles, but does nothing !
}
Live Example.
This technique comes in handy if you want to have int specific behavior without completely disabling the generic behavior.
One approach not given yet in the answers is using the standard library std::enable_if to perform SFINAE on a base class that you inherit to the main class that defines appropriate member functions.
Example code:
template<typename T, class Enable = void>
class A_base;
template<typename T>
class A_base<T, typename std::enable_if<std::is_integral<T>::value>::type>{
public:
void only_for_ints(){/* integer-based function */}
};
template<typename T>
class A_base<T, typename std::enable_if<!std::is_integral<T>::value>::type>{
public:
// maybe specialize for non-int
};
template<typename T>
class A: public A_base<T>{
protected:
std::vector<T> my_vector;
};
This approach would be better than an empty function because you are being more strict about your API and better than a static_cast because it simply won't make it to the inside of the function (it won't exist) and will give you a nice error message at compile time (GCC shows "has no member named ‘only_for_ints’" on my machine).
The downside to this method would be compile time and code bloat, but I don't think it's too hefty.
(don't you dare say that C++11 requirement is a down-side, we're in 2014 god-damnit and the next standard has even be finalized already!)
Also, I noticed, you will probably have to define my_vector in the base class instead of the final because you probably want to handle that data within the member function.
A nice way to do that without duplicating a bunch of code is to create a base base class (good god) and inherit that class in the base class.
Example:
template<typename T>
class base_data{
protected:
std::vector<T> my_vector;
};
template<typename T>
class A_base<T, typename std::enable_if<std::is_integral<T>::value>::type>: public base_bata<T>{
public:
void only_for_ints(){/* phew, finally. fiddle around with my_vector! */}
};
// non-integer A-base
template<typename T>
class A: public A_base<T>{
protected:
// helper functions not available in base
};
That does leave a horrible looking multiple-inheritance scheme, but it is very workable and makes it easy to define members based on template parameters (for future proofing).
People often don't like multiple-inheritance or how complicated/messy SFINAE looks, but I couldn't live without it now that I know of it: the speed of static code with the polymorphism of dynamic code!
Not sure where I found this, but you can use = delete; as the function definition inside the class, thereby deleting the function for the general case, and then explicitly specialize outside the class:
template <typename T>
struct A
{
auto int_only(T) -> void = delete;
};
template <> auto A<int>::int_only(int) -> void {}
int main()
{
auto a_int = A<int>{};
auto a_dbl = A<double>{};
a_int.int_only(0);
// a_dbl.int_only(3.14); error: call to deleted member function
}
https://en.cppreference.com/w/cpp/language/function#Deleted_functions
I have a scenario in which there is a template class
template<typename X, typename Y>
class Foo
{
typedef Y::NestedType Bar;
int A (Bar thing);
void B();
int C(X that);
// other stuff
};
and then I would like the A() method to have a different behavior when X is a given type (but B and C can stay the same, and the actual code actually has about 10 other methods, a few of which are quite lengthy and subject to frequent tweaking.. so I would rather avoid making a full-class specialization and copy&paste the full class implementation)
I went on and wrote:
template<typename T>
int Foo<MyType, T>::A(Bar thing);
but my compiler (clang 163.7.1) refused to even consider this as a template specialization of any sort.
Is there some syntax error hidden in the way I wrote the code, or is this coding style invalid C++? Unfortunately, even if other compilers do support the idiom, my company is stuck with clang.
Thanks for any help on this.
Use overloading
template<typename X, typename Y>
class Foo
{
// allows to wrap up the arguments
template<typename, typename>
struct Types { };
typedef Y::NestedType Bar;
int A (Bar thing) {
return AImpl(thing, Types<X, Y>());
}
void B();
int C(X that);
// other stuff
private:
template<typename X1, typename Y1>
int AImpl(Bar thing, Types<X1, Y1>) {
/* generic */
}
template<typename Y1>
int AImpl(Bar thing, Types<SpecificType, Y1>) {
/* special */
}
};
You cannot partially specialize a member of a class template. What you wrote would be the definition of a member function A of a partial specialization of the class template itself.
One of my classes declares a templated function:
template<class A, class B>
A do_something(const std::vector<B> &data)
which I'd like to partially specialize on typename A. B is a family of types that implement a pretty minimal interface, and we use a lot of them, so I'd like my specialization to be generic on B. I suspect this is doubly vexing as typename A is used only as the return type.
From the internet, I've gleaned that I can't partially specialize a function, so I've created a class as follows:
template<class A, class B>
class do_something_implementation {
public:
do_something_implementation(const std::vector<B> &data_) {
data = data_;
}
int do_something_implementation<int, B>::operator()() {
/* Complicated algorithm goes here... */
}
double do_something_implementation<double, B>::operator()() {
/* Different complicated algorithm goes here... */
}
private:
std::vector<B> data;
}
When I try to compile that (using Visual Studio 2008), the compiler crashes (!) and I get the following error:
fatal error C1001: An internal error has occurred in the compiler.
I assume this is my problem and not the compiler's. Is there a better way to express the partial specialization I'm aiming for?
Usually, it goes like this:
template <typename A, typename B>
struct DoSomethingHelper
{
static A doIt(const std::vector<B> &data);
};
template <typename B>
struct DoSomethingHelper<double, B>
{
static double doIt(const std::vector<B> &data) { ... }
};
template <typename B>
struct DoSomethingHelper<int, B>
{
static int doIt(const std::vector<B> &data) { ... }
};
template<class A, class B>
A do_something(const std::vector<B> &data)
{ return DoSomethingHelper<A, B>::doIt(data); }
Now that you've seen the classic forward to static method, there is actually another way when the type for which to specialize is "complete".
You may not be able to partially specialize a function, but you can perfectly overload it.
template <typename A, typename B>
A do(std::vector<B> const& data) { return this->doImpl(data, (A*)0); }
template <typename A, typename B>
A doImpl(std::vector<B> const& B, A*) { // generic implementation }
template <typename B>
int doImpl(std::vector<B> const& B, int*) { // int implementation }
template <typename B>
double doImpl(std::vector<B> const& B, double*) { // double implementation }
The trick is to pass an "unused" argument to doImpl for the sole purpose of actually selecting the right implementation (thanks to overload resolution).
Here I simply chose to pass (A*)0, because this does not involve A's constructor (in case it's non trivial).
This dispatch idiom is what is used in the STL to implement some algorithm with better efficiency for some iterator categories (for example, std::distance is O(1) for random iterators).
I find it much more lightweight that using a helper class with static methods and partial specializations... but maybe that's just me :)
People typically just forward to a static implementation.
template<class A, class B> class X;
template<class A, class B> friend class X;
template<class A, class B> class X {
public:
static A do_something(class_type* not_this, const std::vector<B>& data) {
//...
}
};
// partially specialize
template<class A, class B>
A do_something(const std::vector<B> &data) {
return X<A, B>::do_something(this, data);
};
Not a solution to your problem (there are a couple already there), but some of the things that are wrong in your code:
You are missing a struct or class keyword in the template class declaration:
template <typename A, typename B> struct do_something_implementation {
// ^^^^^^
Inside the class definition, member functions must not use a qualified name, regardless of whether the class is a template or not:
class A {
void A::foo() {} // Error, should be: void foo() {}
};
Member template specializations cannot appear inside the class definition, but at the namespace level:
class B {
template <typename T> void foo( T );
};
template <> void B::foo<int>( int ) {}
template <> void B::foo<double>( double ) {}
Plus on your case, the member function is not a template, but rather a non-templated member function (the template is the containing class, not the function itself). What your code is effectively trying to do is defining other class' member functions inside the general template, kind of trying to do.
Overall there was enough errors to make parsing the code almost impossible for the compiler to identify what you were trying to do and provide a good error message, but still, it should have provided any error message pointing to the first line that you copied instead of chocking to death.
If I have a template class specification like so,
template <typename T>
class MyClass {
public:
void fun1();
// ...
void funN();
};
template <typename T>
void MyClass<T>::fun1() {
// definition
}
// ...
template <typename T>
void MyClass<T>::funN() {
// definition
}
If I change the class template to something else, say I add an extra parameter:
template <typename T, typename U>
class MyClass {
// ...
};
Then I have to change each function definition (fun1, ..., funN) to agree with the class template specification:
template <typename T, typename U>
void MyClass<T,U>::fun1() { //... }
Are there any strategies for avoiding this? Could I use macros e.g.
#define DFLT_TEMPLATE template<typename T, typename U>
#define DFLT_CLASS class<T,U>
DFLT_TEMPLATE
void DFLT_CLASS::fun1() { // ... }
Or is this considered bad practice?
To me, the benefits of using a macro here are far overshadowed by the drawbacks. Yes, if you use a macro then if you ever need to add an additional template parameter, you'll only need to make a single modification. But anyone else reading your code is probably going to vomit.
I mean, are you going to do this for every template you have? Your code will become infested with ugly macros.
How many member functions do you have that this is an issue?
I think either they are small enough to be defined within the class template or the adaption of their algorithms to an additional template parameter would by far outweigh the replacement of those function headers.
Also, your editor ought to do this for you in no time anyway.
yes you could but don't forget to use "#undef DFLT_TEMPLATE" and "#undef DFLT_CLASS" at the end of file to avoid compiler warnings if your project have several templates with same macros definitions
Inheritation is better than macro.
If you want to change only a few functions and variables, make the specialized class inherit a common class that provides common functions/variables.
As far as possible, put the function definitions in the class template definition. It's a template, so unless you're using Comeau compiler, it's not as if they're going to be off in a different TU.
If the functions use something which is defined in between the class definition and the function definition, then you can play tricks to make that thing dependent on a template parameter even when "really" it isn't. For example:
template <typename T>
struct Foo {
void usebar();
};
struct Bar {
int a;
Foo<int> circularity; // circular dependency between Foo and Bar
Bar() : a(3) {}
};
template <typename T> void Foo<T>::usebar() {
Bar b;
std::cout << b.a << "\n";
}
Becomes:
// we only have to write "same" once
template <typename T, typename U>
struct same {
typedef U type;
};
struct Bar;
template <typename T>
struct Foo {
void usebar() {
typename same<T,Bar>::type b;
std::cout << b.a << "\n";
}
};
struct Bar {
int a;
Foo<int> circularity; // circularity gone
Bar() : a(3) {}
};
Or actually in this case just:
struct Bar;
template <typename T, typename B = Bar>
struct Foo {
void usebar() {
B b;
std::cout << b.a << "\n";
}
};
struct Bar {
int a;
Foo<int> circularity;
Bar() : a(3) {}
};
All cases support the following code:
int main() {
Foo<int> f;
f.usebar();
}
I would consider this approach bad practice. What you are complaining about is that you have changed your design (you need an extra template parameter) and now want a kludge to save on typing?
Introducing macros is going to decrease the readability of your code. Preprocessor definitions certainly have their place, but personally I'd never advocate one on the grounds that I can't be bothered to change my functions.
There are probably some (more or less bad) workarounds, but you definitely point out a " missing" feature of C++: class namespace extension.
Some people already proposed to extend C++ in this way:
http://www.lrde.epita.fr/dload//20080709-Seminar/ordy-classnamespaces.pdf
namespace foo
{
class bar
{
typedef int baz_t;
baz_t my_method ();
};
}
namespace class foo::bar
{
baz_t my_method ()
{
// ...
}
}
--
Using a macro is not a good idea (usual things about macros ....).
I would prefer, at worst, write function members definitions inline in this case, or even better use an editor than can help you easily update your class definition.
Macros are bad because they let you write code editing functions where you are supposed to write programs.
If you want to edit code, use your editor (sed, M-x replace-*, Find&Replace ...)