template <class T>
class Test
{
public:
template<class T>
void f(); //If i define function here itself, error is not reported.
};
template <class T>
void Test<T>::f()
{
} //Error here.
int main()
{
Test<float> ob;
ob.f<int>();
}
It produces below error.
error C2244: 'Test<T>::f' : unable to match function definition to an
existing declaration
definition 'void Test::f(void)'
existing declarations 'void Test::f(void)'
Error says declaration and definitions have the same prototype but not matching.
Why is this an error ? and how to solve it ?
If i define function within the class, it doesn't report error.
But i want to define outside the class.
Change as
template <class T>
class Test
{
public:
template<class U>
void f();
};
template <class T>
template<class U>
void Test<T>::f()
{
}
....
public:
template<class T> // this shadows the previous declaration of typename T
void f();
};
Change the parameter name. Here is the working code.
Related
template <class T>
struct A {
template <class X>
void foo() {}
};
struct B {
template <class T>
void foo() {
A<T>().foo<T>(); // no need of template disambiguator?
}
};
int main() {
return 0;
}
g++-5.4 and -6.2 accept this code, but clang-3.8 doesn't and gives the following error message:
main.cc:11:12: error: use 'template' keyword to treat 'foo' as a
dependent template name
I think that there should be a template. And my question is : Is there any reason that g++ accept this code?
I've recently discovered template specialization in C++.
template <typename T>
void fct(void) {}
template <>
void fct<int>(void) {}
int main(void) {
fct<int>();
return 0;
}
I'd like to use template specialization for member functions inside a class.
class MyClass {
public:
template <typename T>
static void fct(void) {}
template <>
static void fct<int>(void) {}
};
int main(void) {
MyClass::fct<int>();
return 0;
}
Unfortunately, compiling with g++ gives me the following error:
error: explicit specialization in non-namespace scope ‘struct MyClass’
error: template-id ‘toto<int>’ in declaration of primary template
I've noticed that doing template specialization works in main scope or in a namespace but not in a struct or in a class.
I've found something on stackoverflow about using a namespace like in the following code:
namespace myNameSpace {
template <typename T>
void fct(void) {}
template <>
void fct<int>(void) {}
}
class MyClass {
public:
template <typename T>
static void fct(void) {
myNameSpace::fct<T>();
}
};
int main(void) {
MyClass::fct<int>();
return 0;
}
What am I doing wrong? Is it possible to make template specialization with member functions? If not, what is the best way to get around this? Is there a better way than using namespace to get around this?
Write the specialization after the class definition:
class MyClass
{
public:
template <typename T>
static void fct(void) {}
};
template <>
void MyClass::fct<int>() {}
Why does the following code fail to compile?
template <typename T>
struct X
{
template <typename R>
R default_value();
};
template <typename T>
int X<T>::default_value<int>()
{
return -1;
}
it says
x.cpp:17:30: error: template-id ‘default_value<int>’ in declaration of primary template
x.cpp:17:5: error: prototype for ‘int X<T>::default_value()’ does not match any in class ‘X<T>’
x.cpp:13:7: error: candidate is: template<class T> template<class R> R X::default_value()
I also tried to do
template <typename T>
template <>
int X<T>::default_value<int>()
{
return -1;
}
but this gives me another compilation error
prog.cpp:11: error: invalid explicit specialization before '>' token
prog.cpp:11: error: enclosing class templates are not explicitly specialized
prog.cpp:12: error: template-id 'default_value<int>' for 'int X<T>::default_value()' does not match any template declaration
I also tried doing the same for structures
template <typename T>
struct X
{
template <typename R> struct default_value;
};
template <typename T>
template <>
struct X<T>::default_value<int>
{
static int get() { return -1; }
};
same issue.
How to solve that?
One cannot explicitly specialize member templates. Consider:
template <class T>
struct X
{
template <class U> struct Y;
};
...Now (imagine we could do this):
template <class T>
template <>
struct X<T>::Y<int>
{};
...For X of which T are we explicitly specializing?
What if, after the point of definition of our explicit specialization, someone does this in one compilation unit...
void foo()
{
X<int>::Y<int> xy;
}
... and then this in another...(valid code, btw).
template <>
template<>
struct X<int>::Y<int>
{};
void foo()
{
X<int>::Y<int> xy;
}
... which would imply multiple definitions of the same class???
As mentioned previously, this is treated well here
Now, considering that the default value actually depends on the type T, perhaps one can get it from the type T.
template <class T>
struct X
{
static T defaultValue(){ return T::defaultValue(); }
};
or better yet, one could change the behavior of defaultValue based on whether T has the member defaultValue.
template <typename T>
template <>
int X<T>::default_value<int>()
{
return -1;
}
should be fine. Similar topic...
This compiles:
template <class T>
class Bar {};
template<class T, class Dummy=void>
class Foo;
template<class T>
class Foo <T, typename std::enable_if<
std::is_base_of<Bar<T>, T>::value
>::type> {
public:
//THIS CHANGES IN THE 2ND SNIPPET
void test () const {
std::cout << "test";
}
};
class Cat : Bar<Cat> {};
int main () {
Foo<Cat> foo;
foo.test();
return 0;
}
This errors:
template <class T>
class Bar {};
template<class T, class Dummy=void>
class Foo;
template<class T>
class Foo <T, typename std::enable_if<
std::is_base_of<Bar<T>, T>::value
>::type> {
public:
//THIS CHANGED!
void test () const;
};
//THIS WAS ADDED SINCE THE 1ST SNIPPET!
template<class T>
void Foo<T>::test () const {
std::cout << "test";
} //error C2039: 'test' : is not a member of 'Foo<T>'
class Cat : Bar<Cat> {};
int main () {
Foo<Cat> foo;
foo.test();
return 0;
}
I have marked the differences. Why does it error in the 2nd code snippet? How do I keep declaration and definition separate while avoiding the error?
I'm guessing it's got something to do with this:
"template
void Foo::test () const"
Like, this is the wrong way to tell the compiler that the method test() const is a method of template class template class Foo , T>::value >::type>
I've, of course, looked it up on Google and StackOverflow but it seems that, whenever this error pops up for templates, it's a different reason every time. (Probably because a lot of things can cause the C2039 error.)
Also, could a mod. or someone help me add the C2039 tag to this post? It says I need a min. of 1500 rep. to add that tag.
-- Rambling --
It also be noted that it's been a while since I've used C++; and even longer since I've used templates. I know this might be a weird way to use templates but I can assure you I have a valid reason!
An example of out-of-class member declaration for a partially specialized class template is given in 14.5.4.3/1 (C++03). And this is what it looks like
// primary template
template<class T, int I> struct A {
void f();
};
// class template partial specialization
template<class T> struct A<T,2> {
void g();
};
// member of class template partial specialization
template<class T> void A<T,2>::g() { }
As you can see, you have to specify specialized arguments in the out-of-class member definition.
In your case it should be
template<class T>
void Foo<T, typename std::enable_if<
std::is_base_of<Bar<T>, T>::value>::type>::test () const {
std::cout << "test";
}
I used a simple class for a test program about templates, this is what I did:
template <typename T>
class test
{
public:
test<T>::test();
T out();
};
template <typename T>
test<T>::test()
{
}
T test<T>::out()
{
}
int main()
{
//test<int> t;
}
But when I try to compile it says 'T' : undeclared identifier and use of class template requires template argument list , pointing to the same line, where I have implemented the method out() . Can anyone please explain what the problem is?? I'm using visual studio 2008.
Following is more accurate:
template <typename T>
class test
{
public:
test();
T out();
};
template <typename T>
test<T>::test()
{
}
template <typename T>
T test<T>::out()
{
}
1) Don't use <T> inside class
2) Don't forget to declare template <T> before each method declaration out of class body
This line is wrong:
test<T>::test();
Just write this:
test();
Your definition of the out member is missing the template argument list. out should read:-
template <typename T>
T test<T>::out()
{
}