This question already has answers here:
How to call constructor of a template base class in a template derived class?
(2 answers)
Closed 10 months ago.
i am trying to inherit from base class which is template, the derived class is also template, they have same type T. I am getting compile error: illegal member initialization: 'Base' is not a base or member...
Why? How can i call the base class constructor?
#include <iostream>
template<class T>
class Base {
public:
Base(T a) {
std::cout << "A: " << a << std::endl;
}
};
template<class T>
class Derived : public Base<T> {
public:
Derived(T a) :
Base(a) // this is the problem
{}
};
int main() {
int a = 1;
Derived<int> derived(a);
}
Since Base is a template, you need to specify the template parameter in the member initializer list:
Derived(T a) : Base<T>(a) {}
// ^^^
I try to initialize a static member of a CRTP base class. The base class holds a static template member of the derived class, while the derived class defines other data members. I want to statically initialize this variable. In code, a minimal example would be the following:
template<typename DERIVED>
class base {
public:
static DERIVED x;
};
class derived : public base<derived>
{
public:
int a;
};
int base<derived>::x {0};
int main()
{}
However, the above does not compile, but gives the error message error: specializing member 'base<derived>::x' requires 'template<>' syntax.
How can I get the static initialization to work?
The correct syntax is:
template <class T>
class base {
public:
static T x;
};
template <class T>
T base<T>::x{};
Note that you can't initialize x to a specific integer value, since then your base class won't compile when DERIVED is e.g. an std::string.
You probably also want your inheritance to be explicitly public or private. I.e.:
class derived : public base<derived> {
public:
int a;
};
Edit: To specialize x and it's initialization for specific types T, you have to specialize base itself. I.e.:
class A;
template <>
class base<A> {
public:
static int x;
};
// Note missing "template <>" here.
int base<A>::x{ 5 };
class A : public base<A> { };
This seems rather cumbersome, since you need to already forward declare A in this case before declaring the specialization. To me it feels you might want to rethink your design. Is this really required or is there a simpler way to accomplish what you want?
I have found the static initializer trick, which works in the above setting, too. It was described here and here. In the above context, it would be as follows:
#include <iostream>
template<typename DERIVED>
class base {
public:
static inline DERIVED x;
};
class derived : public base<derived>
{
public:
int a;
struct static_initializer {
static_initializer()
{
derived::x.a = 1;
}
};
static inline static_initializer static_initializer_;
};
int main()
{
std::cout << derived::x.a << "\n";
}
The above output the value 1.
Note: this works with C++17.
This question already has answers here:
Why do I have to access template base class members through the this pointer?
(3 answers)
Derived template-class access to base-class member-data
(3 answers)
Using member variables inherited from a templated base class (C++)
(1 answer)
Closed 3 years ago.
I'm having issues with accessing protected members in template subclasses of a template class.
Thing is, if I remove the templates, everything works fine. I know how to work around my problem in an ugly way, by simply writing "using Base::my_protected_member" for every single derived class. But why should I need to do that in the first place ?
Here's a minimal commented example
template<class T>
class Base
{
protected:
T x;
public:
Base(T x) : x(x) {}
};
template<class T>
class Derived : public Base<T>
{
//using Base<T>::x; //why ?!
public:
Derived(T x);
void print();
};
template<class T>
Derived<T>::Derived(T x) : Base<T>(x)
{ cout << x << endl; } //works fine
template<class T>
void Derived<T>::print() { cout << x << endl; } //doesn't work
int main()
{
Derived<int> d(4);
d.print();
}
I don't quite understand what's going on, or how to work around this in a nice way. probably I'm doing something wrong...
This question already has an answer here:
SFINAE method completely disables base class's template method in clang
(1 answer)
Closed 3 years ago.
Given a base class and a derived class, which both provide conditionally enabled operators for specific parameter types using SFINAE:
#include <type_traits>
class Base
{
public:
template<class T, std::enable_if_t<std::is_scalar_v<T>>* = nullptr>
void operator>>(T& value) {
}
};
class Derived: public Base
{
public:
using Base::operator>>;
template<class T, std::enable_if_t<!std::is_scalar_v<T>>* = nullptr>
void operator>>(T& value) {
}
};
int main(int argc, char *argv[])
{
int foo;
Base base;
base >> foo; // this works
Derived derived;
derived >> foo; // this doesn't work, the operator from the base class is not considered
}
then calling an operator defined in the base class on an instance of the derived class will not work, even though it should have been made visible by the appropriate using Base::operator>>; declaration. Why? How can the operator from the base class be made usable without verbosely repeating the declaration/definition?
The problem does not occur if the operator in question is not a template in the base class.
Edit: Tested with msvc 15.9.7 as well as clang.
I think the problem here is that a using declaration only brings the declarations of functions and function templates into a derived class that have signatures which are not overridden by members of the derived class [namespace.udecl]/15. So this code should indeed not compile.
Use free functions instead of class members to fix the problem:
#include <type_traits>
class Base
{
public:
template<class T, std::enable_if_t<std::is_scalar_v<T>>* = nullptr>
friend void operator>>(Base&, T& value) {
}
};
class Derived: public Base
{
public:
template<class T, std::enable_if_t<!std::is_scalar_v<T>>* = nullptr>
friend void operator>>(Derived&, T& value) {
}
};
int main()
{
int foo;
Base base;
base >> foo;
Derived derived;
derived >> foo;
}
live example here
I am trying to use template meta-programming to determine the base class. Is there a way to get the base class automatically without explicitly specializing for each derived class?
class foo { public: char * Name() { return "foo"; }; };
class bar : public foo { public: char * Name() { return "bar"; }; };
template< typename T > struct ClassInfo { typedef T Base; };
template<> struct ClassInfo<bar> { typedef foo Base; };
int main()
{
ClassInfo<foo>::Base A;
ClassInfo<bar>::Base B;
std::cout << A.Name(); //foo
std::cout << B.Name(); //foo
}
for right now any automatic method would need to select the first declared base and would fail for private bases.
It's possible with C++11 and decltype. For that, we'll exploit that a pointer-to-member is not a pointer into the derived class when the member is inherited from a base class.
For example:
struct base{
void f(){}
};
struct derived : base{};
The type of &derived::f will be void (base::*)(), not void (derived::*)(). This was already true in C++03, but it was impossible to get the base class type without actually specifying it. With decltype, it's easy and only needs this little function:
// unimplemented to make sure it's only used
// in unevaluated contexts (sizeof, decltype, alignof)
template<class T, class U>
T base_of(U T::*);
Usage:
#include <iostream>
// unimplemented to make sure it's only used
// in unevaluated contexts (sizeof, decltype, alignof)
template<class T, class R>
T base_of(R T::*);
struct base{
void f(){}
void name(){ std::cout << "base::name()\n"; }
};
struct derived : base{
void name(){ std::cout << "derived::name()\n"; }
};
struct not_deducible : base{
void f(){}
void name(){ std::cout << "not_deducible::name()\n"; }
};
int main(){
decltype(base_of(&derived::f)) a;
decltype(base_of(&base::f)) b;
decltype(base_of(¬_deducible::f)) c;
a.name();
b.name();
c.name();
}
Output:
base::name()
base::name()
not_deducible::name()
As the last example shows, you need to use a member that is actually an inherited member of the base class you're interested in.
There are more flaws, however: The member must also be unambiguously identify a base class member:
struct base2{ void f(){} };
struct not_deducible2 : base, base2{};
int main(){
decltype(base_of(¬_deducible2::f)) x; // error: 'f' is ambiguous
}
That's the best you can get though, without compiler support.
My solutions are not really automatic, but the best I can think of.
Intrusive C++03 solution:
class B {};
class A : public B
{
public:
typedef B Base;
};
Non-intrusive C++03 solution:
class B {};
class A : public B {};
template<class T>
struct TypeInfo;
template<>
struct TypeInfo<A>
{
typedef B Base;
};
I am not aware of any base-class-selecting template, and I'm not sure one exists or is even a good idea. There are many ways in which this breaks extensibility and goes against the spirit of inheritance. When bar publicly inherits foo, bar is a foo for all practical purposes, and client code shouldn't need to distinguish base class and derived class.
A public typedef in the base class often scratches the itches you might need to have scratched and is clearer:
class foo { public: typedef foo name_making_type; ... };
int main() {
Foo::name_making_type a;
Bar::name_making_type b;
}
What's with the base class? Are you a .NET or Java programmer?
C++ supports multiple inheritance, and also does not have a global common base class. So a C++ type may have zero, one, or many base classes. Use of the definite article is therefore contraindicated.
Since the base class makes no sense, there's no way to find it.
I am looking for a portable resolution for similar problems for months. But I don't find it yet.
G++ has __bases and __direct_bases. You can wrap them in a type list and then access any one of its elements, e.g. a std::tuple with std::tuple_element. See libstdc++'s <tr2/type_traits> for usage.
However, this is not portable. Clang++ currently has no such intrinsics.
With C++11, you can create a intrusive method to always have a base_t member, when your class only inherits from one parent:
template<class base_type>
struct labeled_base : public base_type
{
using base_t = base_type; // The original parent type
using base::base; // Inherit constructors
protected:
using base = labeled_base; // The real parent type
};
struct A { virtual void f() {} };
struct my_class : labeled_base<A>
{
my_class() : parent_t(required_params) {}
void f() override
{
// do_something_prefix();
base_t::f();
// do_something_postfix();
}
};
With that class, you will always have a parent_t alias, to call the parent constructors as if it were the base constructors with a (probably) shorter name, and a base_t alias, to make your class non-aware of the base class type name if it's long or heavily templated.
The parent_t alias is protected to don't expose it to the public. If you don't want the base_t alias is public, you can always inherit labeled_base as protected or private, no need of changing the labeled_base class definition.
That base should have 0 runtime or space overhead since its methods are inline, do nothing, and has no own attributes.
Recently when I reading Unreal Engine source code, I found a piece of code meet your requirement.
Simplified code is below:
#include <iostream>
#include <type_traits>
template<typename T>
struct TGetBaseTypeHelper
{
template<typename InternalType> static typename InternalType::DerivedType Test(const typename InternalType::DerivedType*);
template<typename InternalType> static void Test(...);
using Type = decltype(Test<T>(nullptr));
};
struct Base
{
using DerivedType = Base;
static void Print()
{
std::cout << "Base Logger" << std::endl;
}
};
struct Derived1 : Base
{
using BaseType = typename TGetBaseTypeHelper<Derived1>::Type;
using DerivedType = Derived1;
static void Print()
{
std::cout << "Derived1 Logger" << std::endl;
}
};
struct Derived2 : Derived1
{
using BaseType = typename TGetBaseTypeHelper<Derived2>::Type;
using DerivedType = Derived2;
static void Print()
{
std::cout << "Derived2 Logger" << std::endl;
}
};
int main()
{
Derived1::BaseType::Print();
Derived2::BaseType::Print();
}
Using a macro below to wrap those code make it simple:
#define DECLARE_BASE(T) \
public: \
using BaseType = typename TGetBaseTypeHelper<T>::Type; \
using DerivedType = T;
I got confused when first seeing these code. After I read #Xeo 's answer and #juanchopanza 's answer, I got the point.
Here's the keypoint why it works:
The decltype expression is part of the member declaration, which does
not have access to data members or member functions declared after
it.
For example:
In the declaration of class Derived1, when declaring Derived1::BaseType, Derived1::BaseType doesn't know the existence of Derived1::DerivedType. Because Derived1::BaseType is declared before Derived1::DerivedType. So the value of Derived1::BaseType is Base not Derived1.