I've been facing a big challenge (for me, at least) regarding templates instancing and inheritance. Let's see this code:
class Convertible
{
public:
template<class T>
T* AsPtrTo()
{
return reinterpret_cast<T*>(this);
}
};
template<class T>
class TemplateBase : public Convertible
{
};
template<class T>
class TemplateDerived : public TemplateBase<T>
{
public:
void Method1(TemplateBase<T> t)
{
t.AsPtrTo<int>(); // <<<<<< ERROR
}
};
int main()
{
TemplateDerived<int> d;
TemplateBase<int> b;
d.Method1(b);
return 0;
}
As you can see, there is a class, called Convertible, with only one template method that performs a type casting. There is also a template class that inherits from Convertible, and then another template class that inherits from the previous one. This last template class implements a method that uses the template method AsPtrTo which should be inherited from Convertible and instanced during compilation for the type T, used in the main function.
For some reason I can't understand, this fails. GCC 4.4.1 gives me this message:
error: expected primary-expression before 'int'
I've marked the line of the error.
I thought maybe one of the C++ experts here could lend me a hand.
Thanks everybody in advance!
You need to use the keyword template as:
t.template AsPtrTo<int>();
This has been discussed so many times that you will find innumerable number of posts on SO.
But here you will find one of the best explanation:
Where and why do I have to put the "template" and "typename" keywords?
Try:
void Method1(TemplateBase<T> t)
{
t.template AsPtrTo<int>();
}
The reason is that the compiler doesn't know what member functions t has at parse time, so it doesn't know if AsPtrTo is a template function or not. Because of this, it can't parse it properly without the hint.
As an example for why this is needed, consider the following code:
struct Foo
{
template<int N> int foo(int x) { return x + N; }
};
struct Bar
{
int foo;
};
template <typename T>
int baz(T t)
{
return t.foo<0>(1);
}
At a glance, it looks like baz<Foo> would work, but baz<Bar> wouldn't, but it's the other way round!
Consider what happens if I call baz<Bar>
return t.foo<0>(1);
foo is a member variable, so when it sees the < it thinks it's a less-than operator, so it parses the expression like this:
return (t.foo < 0) > (1);
Which is a valid expression (after some implicit conversions to/from bool)!
The thing is, it parses the expression like that for both Foo and Bar, which is why the template keyword is needed. Compilers have to assume that it is not a template member function (unless you put that keyword there).
Related
Somehow I am not able to understand this answer.
When a member function is defined outside class, why can't we have a simple nested name specifier (for example Foo::Foo(){} instead of having a more verbose Foo<T>::Foo(){}), even after the template declaration is repeated right before the member function definition.
The subtlety is that in
template<class T>
int VisitedSet::getSize() {
return vec.size();
}
the C++ compiler would not know yet what T applies to. When you're working inside the class definition for VisitedSet, you can use VisitedSet::... unambiguously, but outside the does not work.
When you're outside the class definition, the syntax requires that you tell the compiler what the template parameters are using the tempate<class T> syntax, and then that you tell the compiler where they apply.
In this case, that may seem ambiguous, but consider the following nested case:
template<class T>
class Foo {
template<class R>
class Bar {
int getSize();
};
};
Then it's more obvious why you need to be specific:
template<class X, class Y>
int Foo<Y>::Bar<X>::getSize() { ...
and
template<class A, class B>
int Foo<A>::Bar<B>::getSize() { ...
are both valid.
So that's why you need
template<class T>
int VisitedSet<T>::getSize() {
return vec.size();
}
even in the simpler case shown in the answer you link to.
The title is a mouthful, but basically I wrote something like this:
enum EnumType{ValA, ValB};
template<EnumType> class A {};
template<>
class A<ValA>
{
private:
double param;
public:
A(double param);
};
template<>
A<ValA>::A(double param)
{
// Do Stuff
}
and when I try to compile it I get:
error: template-id 'A<>' for 'A<(EnumType)0u>::A(double)' does not
match any template declaration
Am I doing this wrong?
After searching online for similar cases, I tried to remove template<> (even though I don't understand why this would work), but then I get
multiple definition of 'A<(EnumType)0u>::A(double)'
I guess that I can replace template<> by inline (I tried and it compiles), but that doesn't feel like the proper way to do it (or if it is, I don't understand why).
Can someone explain to me what is wrong with what I wrote, why changing this seems to work, and what's the proper way to do it ?
Can someone explain to me what is wrong with what I wrote, why changing this seems to work, and what's the proper way to do it ?
The standard says:
Members of an explicitly specialized class template are defined in the same manner as members of normal classes, and not using the template<> syntax.
Therefore, in your case you must use:
A<EnumType::ValA>::A(double param)
{
// Do Stuff
}
No template<> at all is just fine. That's because you are actually specializing a (special) member function (the constructor) of an explicitly specialized class template.
See it on coliru.
It would have been different if no explicit specialization was given.
As a minimal working example:
enum EnumType{ValA, ValB};
template<EnumType> class A
{
private:
double param;
public:
A(double param);
};
template<>
A<EnumType::ValA>::A(double)
{
// Do Stuff
}
int main() {
A<EnumType::ValA> a{0.};
}
In this case, template<> is required before the definition of the constructor because you are not defining a specialization of a member function of an already specialized class template.
You missed a semicolon (;) at the the end of class definition.
And the non template member function can be defined this way:
A<ValA>::A(double param) {
// Do Stuff
}
Informally, the template parameter list is only written when necessary, for example, for defining a member function template of a class template, the two template parameter list should all be written
template<class U, class V>
class A{
template <class T>
A();
};
template<class U, class V>
template <class T>
A<U, V>::A() {}
and a empty template parameter list is needed for a explicit specialisation of function template (which, i guess, is the reason why you use so here), informally because it tells the compiler that this is not a function overloading.
We all know, what is template. Strongly speaking, it is a part of code which is checked for errors only when a copy of it was used and all the arguments where set.
We also know, that the arguments of template must be constant-value expressions. So we cant use variables as the arguments for the template.
But we can see that when template is compiled, the code responsible for it is like copied with the arguments pasted on formal parameters.
Can we use a part of a code as an argument of a template?
For example we have:
template<bool arg>
class foo
{
bool val;
public:
foo() : val(arg) {};
}
Everething is ok, thats works well as arg is an constant value.
But, I want't to use a static part of code, pasted to the template like this:
class foo
{
int a,b,c;
public:
foo() : a(0),b(0),c(0)
{};
foo(int an, int bn, int cn) : a(an),b(bn),c(cn)
{};
template<partOfCode cond>
bool foo_check()
{
if(cond) return true;
else return false;
};
};
int main(char* args, char** argv)
{
foo foovar;
foovar.foo_check<this->a==0>();
//or
foovar.foo_check<a==3>();
};
Of course I get the errors trying to do like this. But if really paste a part of argument code to the template on its place, there will be no any syntax errors at least.
Somebody can answer, that I can use define directive. But that will not help, as template and preprocessor are independent.
Is there a way to implement something like this?
Templates don't copy text like macros do, so you're:
trying to reference this in non-member function
trying to access inaccessible variable
trying to instantiate template with run-time value instead of compile-time constant
You'll have to pass a function:
template <typename FunctionToCall>
bool foo_check(FunctionToCall func)
{
return func(); // simplified
};
// this is how you call it with lambda function
foovar.foo_check([&]{ return foovar.get_a() == 0; }); // still have to provide an accessor, or make a friend function instead
The hell with the template, if you need just function for a condition, you can do
bool foo_check(std::function<bool()> const& func)
{
return func(); // at this point, isn't foo_check useless?
}
Please refer to the below code
Specialized function in non specialized Template class
Is it possible to write a specialized function foo, for non specialized template class MyClass [Line Number 7] ? If yes, then, what is the syntax for the same.
Regards,
Atul
This can be done if you create a full specialization of the class template. Just refer to the answer in this question: If I want to specialise just one method in a template, how do I do it?
Otherwise if you want to have a given function with the same signature have two different behaviors depending on the instantiated version of the class, and that instantiation is a partial specialization of the template class, you will have to make a separate specialization of the template class.
Keep in mind that if you want to avoid redundant code in this second case, you can always create a base template class that will have the functionality that will not change, and then create derived template classes that will contain the unique functionality necessary for each partial specialization.
Look at my example below, I have tried answer your question (if I guessed right) in the simplest code possible by me:
#include <iostream>
using namespace std;
template<typename T>
class Some
{
public:
template<typename U> void foo(U val);
};
template<typename T>
template<typename U>
void Some<T>::foo(U val)
{
cout << "Non specialized" << endl;
}
template<>
template<>
void Some<char>::foo(char val)
{
cout << "Char specialized" << endl;
}
int main()
{
Some<int> t1;
t1.foo(5);
Some<char> t2;
t2.foo('c');
return 0;
}
The important thing to note here is that "You cannot specialize your class and function Independently" i.e you have to specialize both at the same time as done in the example.
Also, with this you lose the opportunity to specialize your class for that data type "char" in this case. (Need to confirm on this).
UPDATE :: Confirmed on point 2.
If you wanted to specialize MyClass< bool >::Foo, it would look like this:
template <>
void MyClass<bool>::Foo(bool A)
{
// code goes here
}
If you are asking that,
(1) you want a function Foo() which doesn't take any argument and
returns void inside MyClass
(2) This Foo() should be exclusive to the MyClass when the
template type is bool, i.e. only for MyClass<bool>
then here is the way:
template<class Precision>
class MyClass {
...
public:
...
void Foo (); // don't implement here
};
...
template<>
void MyClass<bool>::Foo () // implementing only for 'MyClass<bool>'
{ // invoking for other 'MyClass<>' will result in compiler error
...
}
I am trying to write a code that calls a class method given as template parameter. To simplify, you can suppose the method has a single parameter (of an arbitrary type) and returns void. The goal is to avoid boilerplate in the calling site by not typing the parameter type. Here is a code sample:
template <class Method> class WrapMethod {
public:
template <class Object>
Param* getParam() { return ¶m_; }
Run(Object* obj) { (object->*method_)(param_); }
private:
typedef typename boost::mpl::at_c<boost::function_types::parameter_types<Method>, 1>::type Param;
Method method_;
Param param_
};
Now, in the calling site, I can use the method without ever writing the type of the parameter.
Foo foo;
WrapMethod<BOOST_TYPEOF(&Foo::Bar)> foo_bar;
foo_bar.GetParam()->FillWithSomething();
foo_bar.Run(foo);
So, this code works, and is almost what I want. The only problem is that I want to get rid of the BOOST_TYPEOF macro call in the calling site. I would like to be able to write something like WrapMethod<Foo::Bar> foo_bar instead of WrapMethod<BOOST_TYPEOF(&Foo::Bar)> foo_bar.
I suspect this is not possible, since there is no way of referring to a method signature other than using the method signature itself (which is a variable for WrapMethod, and something pretty large to type at the calling site) or getting the method pointer and then doing typeof.
Any hints on how to fix these or different approaches on how to avoid typing the parameter type in the calling site are appreciated.
Just to clarify my needs: the solution must not have the typename Param in the calling site. Also, it cannot call FillWithSomething from inside WrapMethod (or similar). Because that method name can change from Param type to Param type, it needs to live in the calling site. The solution I gave satisfies both these constraints, but needs the ugly BOOST_TYPEOF in the calling site (using it inside WrapMethod or other indirection would be fine since that is code my api users won't see as long as it is correct).
Response:
As far as I can say, there is no possible solution. This boil down to the fact that is impossible to write something like WrapMethod<&Foo::Bar>, if the signature of Bar is not known in advance, even though only the cardinality is necessary. More generally, you can't have template parameters that take values (not types) if the type is not fixed. For example, it is impossible to write something like typeof_literal<0>::type which evalutes to int and typeof_literal<&Foo::Bar>::type, which would evaluate to void (Foo*::)(Param) in my example. Notice that neither BOOST_TYPEOF or decltype would help because they need to live in the caling site and can't be buried deeper in the code. The legitimate but invalid syntax below would solve the problem:
template <template<class T> T value> struct typeof_literal {
typedef decltype(T) type;
};
In C++0x, as pointed in the selected response (and in others using BOOST_AUTO), one can use the auto keyword to achieve the same goal in a different way:
template <class T> WrapMethod<T> GetWrapMethod(T) { return WrapMethod<T>(); }
auto foo_bar = GetWrapMethod(&Foo::Bar);
Write it as:
template <typename Object, typename Param, void (Object::*F)(Param)>
class WrapMethod {
public:
Param* getParam() { return ¶m_; }
void Run(Object* obj) { (obj->*F)(param_); }
private:
Param param_;
};
and
Foo foo;
WrapMethod<Foo, Param, &Foo::Bar> foo_bar;
foo_bar.getParam()->FillWithSomething();
foo_bar.Run(foo);
EDIT: Showing a template function allowing to do the same thing without any special template wrappers:
template <typename Foo, typename Param>
void call(Foo& obj, void (Foo::*f)(Param))
{
Param param;
param.FillWithSomthing();
obj.*f(param);
}
and use it as:
Foo foo;
call(foo, &Foo::Bar);
2nd EDIT: Modifying the template function to take the initialization function as a parameter as well:
template <typename Foo, typename Param>
void call(Foo& obj, void (Foo::*f)(Param), void (Param::*init)())
{
Param param;
param.*init();
obj.*f(param);
}
and use it as:
Foo foo;
call(foo, &Foo::Bar, &Param::FillWithSomething);
If your compiler supports decltype, use decltype:
WrapMethod<decltype(&Foo::Bar)> foo_bar;
EDIT: or, if you really want to save typing and have a C++0x compliant compiler:
template <class T> WrapMethod<T> GetWrapMethod(T) { return WrapMethod<T>(); }
auto foo_bar= GetWrapMethod(&Foo::Bar);
EDIT2: Although, really, if you want it to look pretty you either have to expose users to the intricacies of the C++ language or wrap it yourself in a preprocessor macro:
#define WrapMethodBlah(func) WrapMethod<decltype(func)>
Have you considered using method templates?
template <typename T> void method(T & param)
{
//body
}
Now the compiler is able to implicitly determine parameter type
int i;
bool b;
method(i);
method(b);
Or you can provide type explicitly
method<int>(i);
You can provide specializations for different data types
template <> void method<int>(int param)
{
//body
}
When you are already allowing BOOST_TYEPOF(), consider using BOOST_AUTO() with an object generator function to allow type deduction:
template<class Method> WrapMethod<Method> makeWrapMethod(Method mfp) {
return WrapMethod<Method>(mfp);
}
BOOST_AUTO(foo_bar, makeWrapMethod(&Foo::Bar));
Okay let's have a go at this.
First of all, note that template parameter deduction is available (as noted in a couple of answers) with functions.
So, here is an implementation (sort of):
// WARNING: no virtual destructor, memory leaks, etc...
struct Foo
{
void func(int e) { std::cout << e << std::endl; }
};
template <class Object>
struct Wrapper
{
virtual void Run(Object& o) = 0;
};
template <class Object, class Param>
struct Wrap: Wrapper<Object>
{
typedef void (Object::*member_function)(Param);
Wrap(member_function func, Param param): mFunction(func), mParam(param) {}
member_function mFunction;
Param mParam;
virtual void Run(Object& o) { (o.*mFunction)(mParam); }
};
template <class Object, class Param>
Wrap<Object,Param>* makeWrapper(void (Object::*func)(Param), Param p = Param())
{
return new Wrap<Object,Param>(func, p);
}
int main(int argc, char* argv[])
{
Foo foo;
Wrap<Foo,int>* fooW = makeWrapper(&Foo::func);
fooW->mParam = 1;
fooW->Run(foo);
Wrapper<Foo>* fooW2 = makeWrapper(&Foo::func, 1);
fooW2->Run(foo);
return 0;
}
I think that using a base class is the native C++ way of hiding information by type erasure.