How to create specialization template using scope resolution operator in cpp - c++

template<class t> class Temp{
static t x;
public:
Temp(){};
t increment();
~Temp(){/*body of destructor is important.*/};
};
template<class t>t Temp<t>::x;
template<class t> t Temp<t>::increment(){
return ++x;
}
/*Template specialization starts.*/
template<>class Temp<int>{
int x;
public:
Temp():x(0){};
int increment();
~Temp(){};
};
/*Below is the error part.*/
template<>int Temp<int>::increment(){
return 0;
}
The problem is the last block of code.
Compilation Error
->error: template-id 'increment<>' for 'int Temp::increment()' does not match any template declaration

You don't have to use template<> with specialized member function, because the compiler knows that you are specializing the Temp for int type. So an empty template<> giving the error.
int Temp<int>::increment() {
return ++x;
}
template is used to tell the compiler that T is template param, that's all. But in your case your are specializing for int type, so you don't have to specify template<>. template<> is applicable only for the class and not for member functions defining out side the class.

Related

Error message with operator syntax, but not with function syntax

Why am I getting an error message when calling unary + with operator syntax? If I call it with function syntax, it is OK. Live demo.
template <int size>
struct Buffer { char buf[size]; };
template <class T>
struct Wrapper { void operator+() {} };
Wrapper<Buffer<-5>> a;
void f1() { +a; } // error: Buffer<-5>::buf has negative size
void f2() { a.operator+(); } // OK
The unqualified lookup invokes ADL, which needs to know if there are any friend functions defined in the associated classes. Buffer<-5> is one such, so it is instantiated. The fact that it’s syntactically obvious that it declares no friends doesn’t change the fact that the check for same involves completing the class type, which fails.
As an example let's put Buffer into namespace N, and operator+ into Buffer. If a's type is Wrapper<N::Buffer<5>> (5 rarher than -5), operator+ is found by ADL, and the code compiles (live demo):
template <class T>
struct Wrapper {};
namespace N {
template <int size>
struct Buffer {
template <class T> friend void operator+(const Wrapper<T>&) {}
char buf[size];
};
}
Wrapper<N::Buffer<5>> a;
void f1() { return +a; }

Explicit instantiation of class template not instantiating constructor

I'm working on a project in C++ and am having trouble understanding what members of a template class get explicitly instantiated when I explicitly instantiate the template class. I've written the following file, which I then compile using Visual C++ 2008 Express Edition's Release configuration and then pop into a disassembler.
template<typename T> class test {
public:
template<typename T> test(T param) {
parameter = param;
};
~test() {};
int pop();
int push();
T parameter;
};
template<typename T> int test<T>::push() {return 1;}
template<typename T> int test<T>::pop() {return 2;}
template class test<int>;
int main() {
return 0;
}
Ignoring that this file doesn't really need templates for the moment, this compiles fine. I throw the exe into the disassembler and it tells me that test<int>::pop(void), test<int>::push(void), and test<int>::~test<int>(void) are functions in the exe, but I don't see the constructor. I know I can explicitly instantiate the constructor with
template test<int>::test(int);
which causes test<int>::test<int>(int) to appear in the disassembly as a function with the other ones. My understanding of explicit instantiation is that it is supposed to tell the compiler to instantiate all members of a template class for a given set of arguments, so why is it that the constructor is not explicitly instantiated along with all the other member functions?
When the constructor is a template member function, they are not instantiated unless explicitly used.
You would see the code for the constructor if you make it a non-template member function.
template<typename T> class test {
public:
/***
template<typename T> test(T param) {
parameter = param;
};
***/
test(T param) : parameter(param) {}
~test() {}
int pop();
int push();
T parameter;
};

Is this full template specialization, and is it allowed? [duplicate]

I have a templated class with an templated member function
template<class T>
class A {
public:
template<class CT>
CT function();
};
Now I want to specialize the templated member function in 2 ways. First for having the same type as the class:
template<class T>
template<> // Line gcc gives an error for, see below
T A<T>::function<T>() {
return (T)0.0;
}
Second for type bool:
template<class T>
template<>
bool A<T>::function<bool>() {
return false;
}
Here is how I am trying to test it:
int main() {
A<double> a;
bool b = a.function<bool>();
double d = a.function<double>();
}
Now gcc gives me for the line marked above:
error: invalid explicit specialization before ‘>’ token
error: enclosing class templates are not explicitly specialize
So gcc is telling me, that I have to specialize A, if I want to specialize function, right?
I do not want to do that, I want the type of the outer class to be open ...
Is the final answer: it is not possible? Or is there a way?
Yes, this is the problem:
error: enclosing class templates are not explicitly specialized
You cannot specialize a member without also specializing the class.
What you can do is put the code from function in a separate class and specialize that, much like basic_string depends on a separate char_traits class. Then then non-specialized function can call a helper in the traits class.
You can use overload, if you change the implementation.
template <typename T>
class Foo
{
public:
template <typename CT>
CT function() { return helper((CT*)0); }
private:
template <typename CT>
CT helper(CT*);
T helper(T*) { return (T)0.0; }
bool helper(bool*) { return false; }
};
Simple and easy :)

What is the difference between 2 forms of specialization template implementation in c++

There are 2 different specialization template forms in c++
One is:
#include <iostream>
using namespace std;
template<class T>
class mytest
{
public:
void method(T input){}
};
template<>
void mytest<int>::method(int input)
{
cout << "ok" << endl;
}
int main()
{
mytest<bool> mt;
mt.method(1);
system("pause");
return 0;
}
The other is:
#include <iostream>
using namespace std;
template<class T>
class mytest
{
public:
void method(T input){}
};
void mytest<int>::method(int input)
{
cout << "ok" << endl;
}
int main()
{
mytest<bool> mt;
mt.method(1);
system("pause");
return 0;
}
They can also be compiled in VS2013. I notice that the second implementation of specialization template situation is just lack of template<>
I want to know what the difference is between the 2 forms above.
Visual C++ is wrong.
The standard is very clear about this.
First,
Members of an explicitly specialized class template are defined in the
same manner as members of normal classes, and not using the template<>
syntax.
Meaning that, for explicit specialization of a class template, the member definition strictly do not require template<>.
Example:
template<class T>
struct A {
};
template<>
struct A<int> {
void f(int);
};
// template<> not used for a member of an
// explicitly specialized class template
void A<int>::f(int) { / ... / }
And,
A member or a member template of a class template may be explicitly
specialized for a given implicit instantiation of the class template,
even if the member or member template is defined in the class template
definition. An explicit specialization of a member or member template
is specified using the syntax for explicit specialization.
Meaning that, for a template that is not "explicit specialized", you can specialize its member, with the template<> (syntax for explicit specialization)
Example,
template<class T>
struct A {
void f(T);
};
// specialization
template<>
void A<int>::f(int);
The above examples are directly copied out from standard. To summarize, if the class is already explicitly specialized, do not use template<>, else if the class relies on implicit instantiation, use template<>.
Your first example compiles fine in Clang, and your second example fails to compile in Clang, you will get an error:
error: template specialization requires 'template<>'
template <class T> class mycontainer { ... };
template <> class mycontainer <char> { ... };
The first line is the generic template, and the second one is the specialization.
When we declare specializations for a template class, we must also define all its members, even those identical to the generic template class, because there is no "inheritance" of members from the generic template to the specialization.
http://www.cplusplus.com/doc/tutorial/templates/

Defining member function of explicitly specialized class outside of the class definition

I'm seeing an error related to templates (compiler is Visual Studio 2012) that I don't understand. Here's the code, boiled down to the essentials:
// Templated class - generic
template <typename T>
class Test
{
public:
void WorksFine() {} // Comiples and works as expected at runtime
void Problem();
};
// Templated class - expicit specialization for T = int.
template <>
class Test<int>
{
public:
void WorksFine() {} // Comiples and works as expected at runtime
void Problem();
};
// The definition below compiles and works fine at runtime.
template<typename T> void Test<T>::Problem() {}
// The definition below gives error C2910.
template<> void Test<int>::Problem() {printf("In Test::Problem(int instantiation)\n");}
For the WorksFine method, the function definition is inside the explicitly specialized class definition, and everything is fine. But for the Problem method, when I define the method outside the explicitly specialized class definition, I get error C2910
Why is this? Error C2910 indicates that the problem is that Test::Problem() is already defined. But it is not defined inside the class...there is no function definition only a declaration.
It seems pretty lame to be able to do something or not depending on where you choose to put the function definition, which I always though was more of a style/syntax decision, not a functionality/semantics decision. Am I missing something?
You don't need the template<>. Just write:
void Test<int>::Problem() {printf("In Test::Problem(int instantiation)\n");}
The template<> syntax on a member specialization is required where explicitly instantiating a member on its own; it is omitted when defining a member of an already existing specialization.
template<typename T> struct X { static int i; };
template<> int X<int>::i = 0; // member instantiation, uses template<>
template<typename T> struct Y { static int i; };
template<> struct Y<int> { static int i; } // template specialization
int Y<int>::i = 0; // no template<>
You don't need template anymore in the explicit function definition: void Test<int>::Problem() {printf("In Test::Problem(int instantiation)\n");}
In this case g++ gives a slightly better error message error: template-id 'Problem<>' for 'void Test<int>::Problem()' does not match any template declaration
Try this:
// The definition below gives error C2910.
void Test<int>::Problem()
{
printf("In Test::Problem(int instantiation)\n");
}
int main()
{
Test<int> hey;
hey.Problem();
return 0;
};