Templates in C++ - c++

can we declare a template function in a normal class with out a template class or is it should be always inside a template class ?

can we declare a template function in a normal class with out a template class
Yes we can. For example
class demo
{
public:
template <typename T>
void func(const T& x) {
//do stuffs
}
};
int main()
{
demo d;
d.func<int>(5);
}
is perfectly valid

Yes, you can have template functions in non-templated classes too, e.g.:
struct X {
template<class T>
void f(const T& t) {
// ...
}
};

Yes you can , but make sure your definition and declaration of the template function is in the header files. If you want to know more why is this like that or more about templates in general i can recommend you this book Templates - Complete Guide

Related

Why do we need 'template <class T>' before implementing all templated class methods

If we have a standard class:
class Foo {
public:
int fooVar = 10;
int getFooVar();
}
The implementation for getFooVar() would be:
int Foo::getFooVar() {
return fooVar;
}
But in a templated class:
template <class T>
class Bar {
public:
int barVar = 10;
int getBarVar();
}
The implementation for getBarVar() must be:
template <class T>
int Bar<T>::getBarVar(){
return barVar();
}
Why must we have the template <class T> line before the function implementation of getBarVar and Bar<T>:: (as opposed to just Bar::), considering the fact that the function doesn't use any templated variables?
You need it because Bar is not a class, it's a template. Bar<T> is the class.
Bar itself is a template, as the other answers said.
But let's now assume that you don't need it, after all, you specified this, and I added another template argument:
template<typename T1, typename T2>
class Bar
{
void something();
};
Why:
template<typename T1, typename T2>
void Bar<T1, T2>::something(){}
And not:
void Bar::something(){}
What would happen if you wanted to specialize your implementation for one type T1, but not the other one? You would need to add that information. And that's where this template declaration comes into play and why you also need it for the general implementation (IMHO).
template<typename T>
void Bar<T, int>::something(){}
When you instantiate the class, the compiler checks if implementations are there. But at the time you write the code, the final type (i.e. the instantiated type) is not known.
Hence the compiler instantiates the definitions for you, and if the compiler should instantiate something it needs to be templated.
Any answer to this question boils down to "because the standard says so". However, instead of reciting standardese, let's examine what else is forbidden (because the errors help us understand what the language expects). The "single template" case is exhausted pretty quickly, so let's consider the following:
template<class T>
class A
{
template<class X>
void foo(X);
};
Maybe we can use a single template argument for both?
template<class U>
void A<U>::foo(U u)
{
return;
}
error: out-of-line definition of 'foo' does not match any declaration in 'A<T>'
No, we cannot. Well, maybe like this?
template<class U>
void A<U>::foo<U>(U u)
{
return;
}
error: cannot specialize a member of an unspecialized template
No. And this?
template<class U, class V>
void A<U>::foo(V u)
{
return;
}
error: too many template parameters in template redeclaration
How about using a default to emulate the matching?
template<class U>
template<class V = U>
void A<U>::foo(V u)
{
return;
}
error: cannot add a default template argument to the definition of a member of a class template
Clearly, the compiler is worried about matching the declaration. That's because the compiler doesn't match template definitions to specific calls (as one might be used to from a functional language) but to the template declaration. (Code so far here).
So on a basic level, the answer is "because the template definition must match the template declaration". This still leaves open the question "why can we not just omit the class template parameters then?" (as far as I can tell no ambiguity for the template can exist so repeating the template parameters does not help) though...
Consider a function template declaration
tempalte <typename T>
void foo();
now a definition
void foo() { std::cout << "Hello World"; }
is either a specialization of the above template or an overload. You have to pick either of the two. For example
#include <iostream>
template <typename T>
void foo();
void foo() { std::cout << "overload\n"; }
template <typename T>
void foo() { std::cout << "specialization\n"; }
int main() {
foo();
foo<int>();
}
Prints:
overload
specialization
The short answer to your question is: Thats how the rules are, though if you could ommit the template <typename T> from a definition of the template, a different way would be required to define an overload.

Enable member functions of class templates using concepts

So I have a concept Fooable:
template <typename T>
concept bool Fooable()
{
return requires(...){ ... };
}
And I have a class template Bar that takes type T as template parameter and I want to enable a member function only if T is Fooable:
template <typename T>
class Bar
{
public:
template // ???
requires Fooable<T>
void MemFun();
};
Is it possible in C++17 with concepts TS or in C++2a?
In both the Concepts TS and C++20 designs, functions have an optional trailing requires-clause. So you don't need to make your member function a template to constrain it:
void MemFun() requires Fooable<T>;
Constraints can go after the function in the trailing position:
template <typename T>
class Bar
{
public:
void MemFun() requires Fooable<T>;
};
Live on Godbolt

Passing template prototype as template argument - is it possible?

So first, apologies for terminology - I'm not sure if template prototype is the correct term. By this I mean :
template <class T, class X>
class TemplatePrototype
{
// code
};
I have a situation where I have a function that creates a template object based upon template arguments to that function.
template <class T, class X>
void doSomething()
{
TemplatePrototype<T, X> aTemplateTX;
aTemplateTX.doSomethingElse();
}
However, there are about 15 different versions of TemplatePrototype, which all have the same interface but different execution (TemplatePrototype is provided by another library). As a result, I have a lot of code that looks like this:
template <class T, class X>
void doSomethingWithOne()
{
TemplatePrototypeOne<T, X> aTemplateTX;
aTemplateTX.doSomethingElse();
}
template <class T, class X>
void doSomethingWithTwo()
{
TemplatePrototypeTwo<T, X> aTemplateTX;
aTemplateTX.doSomethingElse();
}
As a consequence of the architecture, I must know which TemplatePrototype I am going to use before I know the actual types T and X. I would like to see something like this:
template <class T, class X, class Prototype>
void doSomething()
{
Prototype<T, X> aPrototype;
aPrototype.doSomething();
}
But where I have specified part of the template arguments in advance - i.e I specify Prototype before I know T and X. Obviously, this is not possible in C++.
Equally, I cannot pass the Prototype as a template argument because it will still result in huge amounts of duplicate code.
Some important facts : I know the range of all possible inputs.
So I could theoretically use a macro to define each possible template specialisation and insert them into a container, which I would then use to access the specialisation I need. However, I am looking for a more 'elegant' solution - is it possible to pass template prototypes without specialising them as an argument to a template class, and then instantiate later when a function is called? Example:
template <class Prototype>
class Holder
{
template <class T, class X>
void doSomething()
{
Prototype<T, X> aPrototype;
aPrototype.doSomethingElse();
}
};
As far as I know this is impossible, but I was wondering if the SO community had some folks who know a solution?
EDIT:
So I have implemented this as my solution, thanks to the answers below!
#include <iostream>
template <typename T>
struct Foo
{
Foo() { aPtr = 0; }
T* aPtr;
};
template <template<typename> class C>
struct Bar
{
template <class T>
void doSomething()
{
C<T> aClass;
if (aClass.aPtr)
std::cout << "Hello world" << std::endl;
}
};
int main()
{
Bar<Foo> aFoo;
aFoo.doSomething<int>();
return 0;
}
This enables me to specify which TemplatePrototype I wish to use, before I can know the template parameters.
Yes, use a template template parameter, e.g.
template <typename T>
struct Foo
{
};
template <template<typename> class C>
struct Bar
{
};
then
Bar<Foo> b;
You're looking for template template parameters.
In the template parameter list, instead of just:
class TemplatePrototype
specify your prototype as a class template which itself has two template type parameters (without giving them a name here), like:
template<class,class> class TemplatePrototype
//^^^^^^^^^^^^^^^^^^^
This will result in a function like:
template <class T, class X,
template<class,class> class TemplatePrototype>
void doSomething()
{
TemplatePrototype<T, X> aTemplateTX;
aTemplateTX.doSomethingElse();
}
Invocation example:
doSomething<T, X, TemplatePrototypeOne>();
To become independent of the number of template parameters you pass to your "prototype" (here it was 2, namely T and X), you can use variadic templates (since C++11).
For this, first move the prototype template parameter to the first position:
template <template<class,class> class TemplatePrototype,
class T, class X>
Then, replace class T, class X with class ...Ts, which is a placeholder of an arbitrary number of type parameters. Also, in the template template parameter list, replace class,class with class.... And in the instantiation within the function implementation, replace <T, X> with <Ts...> to "expand" the parameter pack.
The result then looks like this:
template <template<class...> class TemplatePrototype,
class ... Ts>
void doSomething()
{
TemplatePrototype<Ts...> aTemplateTs;
aTemplateTs.doSomethingElse();
}
Live demo

"used without template parameters"

I realize similar questions have been asked before, but I read a couple of those and still don't see where I'm going wrong. When I simply write my class without separating the prototype from the definition, everything works fine. The problem happens when I separate the prototype and definition as shown below:
template<class T> class VisitedSet {
public:
VisitedSet();
int getSize();
void addSolution(const T& soln);
void evaluate();
private:
vector<T> vec;
int iteration;
};
And as an example of a definition that gives me this error:
int VisitedSet::getSize() {
return vec.size();
I've never made a templated class before, so please pardon me if the problem here is trivial.
VisitedSet is a template, not a class, so you can’t use VisitedSet in a nested name specifier such as VisitedSet::getSize(). Just as you specified the declaration of class VisitedSet<T> for all class T, you must specify the definition of VisitedSet<T>::getSize() for all class T:
template<class T>
int VisitedSet<T>::getSize() {
// ^^^
return vec.size();
}
The name of a template can, however, be used as though it were a class within a template definition:
template<class T>
struct Example {
Example* parent;
T x, y;
};
In this case, Example is short for Example<T>.
You want this:
template <class T>
int VisitedSet<T>::getSize() {
return vec.size();
}
You have to state the template parameter in the definition as well
template<class T>
int VisitedSet<T>::getSize() {
return vec.size();
}
otherwise the compiler cannot match it to the declaration. For example, there could be specializations for some parameter types.
You need to let your compiler know that you are implementing a method in template function:
template<typename T>
int VisitedSet<T>::getSize() {
return vec.size();
}
Try putting
template <typename T>
above the implementation of VisitedSet::getSize() -- but beware that, in general, templated classes and functions should all be inlined. See the c++ faq here for more information.

Template Return Types / Cast as function of Template

I'm working with some generated classes with broken polymorphism. For every generated class T, there are a handful of T_type_info, T_writer, T_reader classes which are only related to T conceptually.
What I'm trying to do is something like this:
template <class T> class Wrapper
{
public:
template <class W> W topic_cast(BrokenBaseClassWriter* p);
// other operations with the same problem ...
};
template <> class Wrapper<MyTopic>
{
public:
template <> MyTopicWriter* topic_cast(BrokenBaseClassWriter* p) { ... }
};
So that I can do things like:
void Write(const Wrapper<T>& topic)
{
BrokenBaseClassWriter p = not_important;
topic.topic_cast(p)->do_stuff();
}
My T classes are generated from an IDL and are concepts that exist in application space. They don't derive from anything. In my example above, W is not really an independent parameter, it's "Something Not T that depends on T". I'm trying to keep all knowledge of T in the app, and all knowledge of T' (without knowing about T) in the backend.
The compiler however says my topic_cast function is not a template function - I think because the template occurs in the return type and it wouldn't be distinguishable from any other instantiations. I know that that (templates differ only by return type) is not legal. Only in my case it really would be unique because W is not an independent parameter. But arguing with the compiler is seldom helpful.
Can I do this, or is there another way to do this "cast as function of template type"?
Could this not be achieved with a traits system?
template <typename T> struct my_traits
{
};
template <> struct my_traits<MyClass>
{
typedef MyWriter writer_type;
};
template <typename T> struct Wrapper
{
typename my_traits<T>::writer_type topic_cast();
};
This can't work:
topic.topic_cast(p)->do_stuff();
Because the compiler can not deduce the return type.
So you have to explicitly tell the compiler what return type you want:
topic.topic_cast<MyType>(p)->do_stuff();
The implementation you provide is for a specific type.
So when you use that specific type that code will be produced:
topic.topic_cast<MyTopicWriter>(p)->do_stuff(); // Use the explicit specialization
This compiles with gcc:
class BrokenBaseClassWriter;
class MyTopic;
class MyTopicWriter;
template <class T> class Wrapper
{
public:
template <class W> W *topic_cast(BrokenBaseClassWriter* p);
// other operations with the same problem ...
};
template <> template<>
MyTopicWriter *Wrapper<MyTopic>::topic_cast<MyTopicWriter>(BrokenBaseClassWriter* p)
{
return 0;
}
int main(int argc, int argv)
{
BrokenBaseClassWriter* p = NULL;
Wrapper<MyTopic> caster;
MyTopicWriter *casted = caster.topic_cast<MyTopicWriter>(p);
}
Of course, it still exposes MyTopicWriter in your main code...