This question already has answers here:
Check if class is derived from a specific class (compile, runtime both answers available)
(6 answers)
Closed 3 years ago.
Suppose I'm writing the following templated function:
class A { /* ... */ };
// ... etc...
template<typename C>
void foo() {
bool C_inherits_A = /* magic */;
if (C_inherits_A) { do_something(); }
else { do_something_else(); }
}
We remember dynamic_cast from the olden days, but that isn't relevant here since there's no pointer, and I'm checking "downward", not "upward". Is there something simple with which to replace /* magic */ in the snippet above?
PS - There should definitely already be a dupe of this question, but I just could not find one so I wrote it up.
Beginning in C++11, the standard C++ library caters to this exact need - using the std::is_base_of type trait. To read a bit more about type traits see their SO tag page.
Anyway, you would replace /* magic */ with:
std::is_base_of<A, C>::value
which is a Boolean expression that's true if A is a base class of C, i.e. if C inherits A.
Remember that type traits are evaluated at compile-time, so you can use if (std::is_base_of<A,C>::value) in constexpr functions, or in template parameters and so on.
Related
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:
Templates polymorphism
(7 answers)
Closed 1 year ago.
Here is my scenario:
class Container {};
class Papa {};
class Child: public Papa {};
void myFunction(Container<Papa> container);
Now I want to pass two different parameters to myFunction().
int main()
{
Container<Papa> papaContainer;
Container<Child> childContainer;
myFunction(papaContainer);
myFunction(childContainer); // this line is not working
}
apparently I cannot do this.
no suitable user-defined conversion from "Container<Child>" to "Container<Papa>"
What would be the solution for this case? How Container<Papa> can be used as interface here?
This seems similar to this question here: No Suitable User Defined Conversion
although that one is using numeric types. Is there anything in myFunction, or that myFunction returns that would need to differentiate Child from Papa?
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 answers here:
Closed 10 years ago.
Possible Duplicate:
Dynamic dispatching of template functions?
I would like to use non-type templates to create grid cells with different memory footprints without having to use dynamically allocated memory on the heap, e.g.
template <int cell_size>
class myCell {...}
There is a finite number of cell sizes (approx. 10), thus I can easily instantiate all of them explicitly. However, which one of the cells are needed is not known at compile time but during runtime only.
I know that templates are a compile-time concept, but is there a way to use templated classes in this way, especially since I can guarantee that all necessary cell types are explicitly instantiated?
You can use factory pattern, but you'll need a base class as a return type:
template <int cell_size>
class myCell : public cellBase {...}
struct CellFactory
{
static cellBase* getCell(int cell_size)
{
switch (cell_size)
{
case 1:
return new myCell<1>;
break;
//and so on
}
}
}
This works because you're telling the compiler which specializations it can expect. But I think that a better design exists for the underlying problem you're trying to solve.
This question already has answers here:
Restrict C++ Template Parameter to Subclass
(8 answers)
Closed 7 years ago.
Is there any way to make a template only work with child classes of a base class? Something like this:
template<BaseClass T>
class FooBar
{
// ...
};
Either use a static assert from your favourite C++ library (such as this boost example), or put a call in the constructor (or other code which will always be generated when the code is used) to a do-nothing function taking a BaseClass type, for example:
template<class T>
class FooBar
{
public:
FooBar () {
Check(static_cast<T*>(0));
}
private:
void Check ( BaseClasse* ) {}
};
(not tested)
Not directly, but you can test it in the constructor using Boost:
#include <boost/type_traits/is_base_of.hpp>
#include <boost/static_assert.hpp>
template<class T>
class FooBar{
FooBar(){
BOOST_STATIC_ASSERT(boost::is_base_of<BaseClass,T>::value);
}
};
Or if you don't want a static assert, something like this is also nice sometimes:
typedef char ERROR_T_must_be_derived_from_BaseClass[boost::is_base_of<BaseClass,T>::value ? 1 : -1];
Since whoever compiles your code will be brought to this line and has a "readable" error message.
There are ways to make it work with a static assert. See Boost.StaticAssert