This question already has answers here:
C++ template constructor
(10 answers)
Closed 9 years ago.
A templated member function, with template arguments not used in the parameter list can be called in the following form:
struct C { template <class> func (); };
C c;
C.func <int>();
But how do I call a template constructor, which does not use a template parameter in its argument list?
struct D { template <class> D (); };
Certainly
D<int> d;
Cannot be the syntax, as this is the construction of a variable of type D <int>,, which is an instantiation of class template D<class>.
This is not just an academic question, I have use for templated constructors (not using the template in the constructor argument list), basically policybased factories and currently use a dummy parameter mpl::identity <mytype>() as a workaround.
This is not my own knowledge, but instead taken from a few other sources, mainly the already posted C++ template constructor.
I assume, that it is not possible to instanciate template-constructors without parameters, because this could create multiple default constructors. Templates are expanded at compile-time and thus create some kind of overload on the function they create. The default-constructor cannot be overloaded, so this has to fail when you use more than one template-instance.
Apart from the dummy-variable I can only think of using a templated factory method or class (if that is possible in your case)
ex: (Using an int-template instead of class-template, since I can't think of another example at the moment)
class C
{
int i;
C() { }
public:
template<int I>
static C newInstance()
{
C c;
c.i = I;
return c;
}
};
Related
This question already has an answer here:
Questions about template and typename [duplicate]
(1 answer)
Closed 5 months ago.
I read this article but I don't understand the meaning of this part of the code:
template <typename T> struct counted : T, private instance_counter<T>
{
using T::T;
};
It must be something simple as "make visible all names from namespace" but I don't completely understand it.
T is the base class.
T::T is/are the constructor(s) of the base class T. A constructor has the same name as the class being constructed.
using T::T; brings the constructor(s) of the base class into the current scope, which is the derived class counted.
This line allows counted to be constructed using any constructor that T allows.
make visible all names from namespace
No, because T isn't a namespace. You can't derive from a namespace.
The using keyword has more than one meaning.
You're thinking of the using directive for namespaces, but the using declaration works for both namespace members (at namespace scope) and class members (inside a class). Since we already established T is not a namespace, this is obviously the second case.
Inside a class using T::member would normally just prevent base-class names being hidden by the derived class, but T::T means the base class constructor, which as a special case inherits constructors from T.
template <typename T> struct counted : T
{
using T::T; // now counted<T> can directly use any of T's constructors
};
This question already has an answer here:
Function with different return type based on the string representation of the type as argument
(1 answer)
Closed 6 months ago.
In the code snippet below, what should I put as the template for MyOtherClass in the return type of the `MyClass::create`` function ?
To make it easier, I can make A , B, C classes all inherit a common class.
And is there a more elegant way of doing this?
template<class MyTemplateClass>
class MyOtherClass{
//
};
class MyClass{
public:
MyOtherClass<//What do I put here?>
MyClass::create(const std::string& input){
if (input == "a"){
return MyOtherClass<A>(); //A is a class
}
if (input == "b"){
return MyOtherClass<B>(); // B is a class
}
return MyOtherClass<C>(); // C is a class
}
};
Short answer is, you can't as is.
You can do something like this either through inheritance (A, B and C inherits from a common base class),
or with std::variant, or with type erasure (MyOtherClass inherits from something)
The question is more about how do you plan on using what comes out of the function?
This question already has answers here:
Is emulating pure virtual function in static polymorphism using CRTP possible?
(3 answers)
Templated check for the existence of a class member function?
(33 answers)
Closed 1 year ago.
I am using CTRP to define an interface in C++ as follows:
template <typename T>
class Interface {
public:
inline void foo() { static_cast<T*>(this)->foo(); }
};
class Implementation : public Interface<Implementation> {
public:
void foo();
};
Thus, if the Interface is used as such:
template <typename T>
void interfaceUser(Interface<T>& i) {
i.foo();
}
This will end up calling the foo() method of the implementation.
However, the flaw in this method (which I would like to keep because the method names of the interface and implementation are the same), is that, if the implementation does not implement the method, the code still compiles but causes an infinite loop.
My question is, is there some way to use static_assert to compare the pointers of Interface::foo and static_cast<T*>(this)->foo to ensure that they are NOT the same and thus, that the function has been implemented?
Also, please let me know if I am going about this in completely the wrong way.
Thanks
This question already has an answer here:
constructor without parameters doesnt work but one with does work [duplicate]
(1 answer)
Closed 2 years ago.
I have a generic class defined down below,
with member parameter an array, i.e. T grades[5];
when I declare object of this class, using
StudentRecord<int> srInt();
and then call a member function of the class, using
srInt.setGrades(arrayInt);
I get an error,
error: request for member ‘setGrades’ in ‘srInt’, which is of non-class type ‘StudentRecord<int>()’
srInt.setGrades(arrayInt);
but when i declare class using(below), and try to call same function, it works
StudentRecord<int> srInt;
//header file for main.cpp
#include<iostream>
using namespace std;
const int SIZE=5;
template <class T>
class StudentRecord
{
private:
const int size = SIZE;
T grades[5];
public:
void setGrades(T* input);
};
template<class T>
void StudentRecord<T>::setGrades(T* input)
{
for(int i=0; i<SIZE;++i)
{
grades[i] = input[i];
}
}
My question is there any difference between declaring class,
StudentRecord<int> srInt();
v/s
StudentRecord<int> srInt;
This is not about templates ("generic class").
Just like int f(); is a function declaration, StudentRecord<int> srInt();s is a function declaration. Yes, even when you write it in a function.
Remove the () and you get an object declaration instead.
That's it!
Some people call this the "Most vexing parse", though it is not actually an example of that. It does involve some of the same grammar/language rules to a degree.
When you wrote StudentRecord<int> srInt(-1);, that is a valid object declaration, because there is no way it can be a function declaration (-1 is not an argument declaration).
If -1 were swapped for a more complex expression, it's possible to get surprised by the fact that it gets interpreted as a valid argument declaration. Like int f(int());. That's the most vexing parse.
There's no magic or strangeness here; you just have to use the right symbols for what you want.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Template type deduction in C++ for Class vs Function?
When calling a template function, you don't need to specify the template parameters if they are non-ambiguous from your parameters. E.g. for:
template<typename T> T foo(T a) { /*...*/ }
You can just call foo(1) and it will work, it does not need to be foo<int>(1).
This is not true for classes/structs, even if it would be clear from the constructor parameters. For example:
template<typename T> struct Foo { Foo(T a) { /*...*/ } };
Now I cannot do just a do_something_with(Foo(1)), it must be do_something_with(Foo<int>(1)).
Often, to work around this issue, there are just some simple wrapper functions which basically just wrap the constructor. That is even in the STL: std::make_pair is such an example.
Now the question: Why is that? Is there any rational reason behind it?
As far as I know, function templates and class templates are different for the lulz and there's no real reason that they should be different from each other. Of course, class templates have partial specializations (T*) as an advantage.