CRTP Singleton Incomplete type or Non-literal type

Related searches

I'm trying to make a CRTP Singleton. There's a couple examples on here already. I'm not sure how mine is different or why it fails to compile. First attempt:

template<class Impl>
class Base
{
public:
  static const Impl& getInstance();
  static int foo(int x);
private:
  static const Impl impl{};
};
template<class Impl> inline
const Impl& Base<Impl>::getInstance()
{
  return impl;
}
template<class Impl> inline
int Base<Impl>::foo(int x)
{
  return impl.foo_impl(x);
}

class Derived1 : public Base<Derived1>
{
public:
  int foo_impl(int x) const;
};
int Derived1::foo_impl(int x) const
{
  return x + 3;
}

int main(int argc, char** argv)
{
  const Derived1& d = Derived1::getInstance();
  std::cout << Derived1::foo(3) << std::endl;
  return 0;
}

g++ 7.4.0 tells me: error: in-class initialization of static data member ‘const Derived1 Base<Derived1>::impl’ of incomplete type.

Well. Ok then. Not sure why that type isn't complete. Try:

 . . .
 private:
   static constexpr Impl impl{};
 };

Now we fail at link time: undefined reference to 'Base<Derived1>::impl' Really?! Looks defined and initialized to me... But even if it did link I have a Derived with a non-trivial destructor so then the compiler is going to bomb at compiletime complaining about a non-literal type used in constexpr.

Why isn't Derived1 complete? How can I build this?


The incomplete type error comes from the fact that you use impl in getInstance before it exists.

One way to fix this is initializing impl outside the class definition and make sure it's initialized before being used:

template <class Impl>
const Impl Base<Impl>::impl {};

CRTP Singleton Incomplete type or Non-literal type, CRTP Singleton Incomplete type or Non-literal type. 发布于 2020-05-03 07:51:29. I'm trying to make a CRTP Singleton. There's a couple examples on here� c++,c++11,typetraits,crtp,static-assert. This is a common problem when using CRTP: Base<Derived> is instantiated at the point where it is encountered in Derived's list of bases, at which time Derived is not yet a complete type since the rest of its declaration hasn't been parsed yet. There are various workarounds. For static_assert, you


Try implementing your getInstance function in this way:

template <class Impl>
inline const Impl& Base<Impl>::getInstance() {
    static const Impl impl{};
    return impl;
}

and then in foo function

template <class Impl>
inline int Base<Impl>::foo(int x) {
    return getInstance().foo_impl(x);
}

Demo

[PDF] More C++ Idioms/Print Version, issue a warning when an incomplete type is deleted, but unfortunately, not all do, and programmers sometimes Singleton pattern implementations often use this idiom. binds to an rvalue (temporary object, literal), the copy is typically elided, which In CRTP idiom, a class T, inherits from a template that specializes on T. Stack Overflow Public questions and answers; Teams Private questions and answers for your team; Enterprise Private self-hosted questions and answers for your enterprise; Jobs Programming and related technical career opportunities


To the point of time that Base<Derived1> is instantiated (right at the start of the definition of Derived1) the class Derived1 is incomplete, since it is that untill the end of its declaration. It is indeed not possible to have a complete type in the CRTP, since the derived type will never be complete before you have declared its inheritance.

For non-static data members the only way around that is to use some kind of pointer to the incomplete type (most probably a std::unique_ptr). For static members this does also work, but can also just split the declaration and the definition of a static member. So instead of

template<Impl>
struct Base {
   static Impl impl{};
};

write

template<Impl>
struct Base {
    static Impl impl;
};

and define it like this

template<Impl>
static Base<Impl>::impl ={};

after Derived1 is complete. (Note that I am not sure how this works for private static members). In my opinion it would be cleanest, if each implementation would do this for itself, i.e. after Derived1 is complete add

template<>
static Base<Derived1>::impl = {};

otherwise getting the order right for multiple implementations will be tricky, I think.

Newest 'crtp' Questions, Solved by this post C++ CRTP initialization I hope this question has not been asked before, as I've CRTP Singleton Incomplete type or Non-literal type. Teams. Q&A for Work. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information.


C++, Copying vs Assignment � Curiously Recurring Template Pattern (CRTP) � Data Structures in Non-static member functions can modify static member variables. Due to this, static variables can be incomplete types (apart from void ), as long as As of C++11, static member variables of LiteralType types (types that can be � How does this change in C++11? C++11 relaxes the restriction to certain extent. C++11 9.4.2 Static data members §3 . If a static data member is of const literal type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression.


C++ Compiler Front-End Fixes In VS2015, [Now] Template function type is not able to be deduced when function taking Wrong line numbers in debugger when multiline literal is present [template alias] C1001 with CRTP and alias template using deduced return type std:: __GetExceptionInfo crashes MSVC 2015 when given an incomplete type. Bridge Design Pattern in C++ Back to Bridge description Bridge design pattern demo. Discussion. The motivation is to decouple the Time interface from the Time implementation, while still allowing the abstraction and the realization to each be modelled with their own inheritance hierarchy.


Cpp Idioms (raw has better view). GitHub Gist: instantly share code, notes, and snippets.