How to initialize non-movable and non-copyable class member - boost::optional - c++11

I have a non-movable and non-copyable type:
struct A
{
A(std::string p1, int p2){}
A(A const &) = delete;
A(A&&) = delete;
A& operator=(A const &) = delete;
A& operator=(A&) = delete;
};
I can construct boost optional this way:
boost::optional<A> op(boost::in_place("abc", 5));
I also need to initialize boost::optional<A> which is a class member. Here is my solution:
class B
{
public:
B(const boost::optional<A>& op): op_(op) {}
private:
const boost::optional<A>& op_;
};
B b(boost::optional<A>(boost::in_place("abc", 5)));
Is it possible to have just boost::optional<A> class member and initialize it somehow ?
Edit (clarification)
I would like to have boost::optional<A> op_ class data member but I don't know how to initialize it.

You can declare the constructor of B as
class B {
public:
B(std::string p1, int p2) :
op_(boost::in_place<A>(std::move(p1), p2)) {}
private:
const boost::optional<A> op_;
};
and instantiate B as
B b("abc", 5);
Note that I change the data member op_ to not be reference here, as opposed to the definition of B in your question.

Related

Is it thread safe to use new in meyer's singleton implementation?

We know that Meyers Singleton is thread safe since c++11.
I'm using this singleton pattern.
struct singleton_t
{
static
singleton_t &
instance()
{
static singleton_t s;
return s;
} // instance
singleton_t(const singleton_t &) = delete;
singleton_t & operator = (const singleton_t &) = delete;
private:
singleton_t() {}
~singleton_t() {}
}; // struct singleton_t
singleton_t is not a pointer or reference so the polymorphism doesn't apply.
Now I want to do it something like this:
struct singleton_t
{
static
singleton_t *
instance(singleton_t* p = nullptr)
{
static singleton_t *s = nullptr == p ? new singleton_t : p;
return s;
} // instance
singleton_t(const singleton_t &) = delete;
singleton_t & operator = (const singleton_t &) = delete;
private:
singleton_t() {}
~singleton_t() {}
}; // struct singleton_t
In this way, I singleton_t can point to instance of its subclass so the polymorphism can be achieved. Or is there a better approach?

Generate one method per type from variadic class template

I would like to have a variadic class template to generate one method per type, such that for example a class template like the following:
template <class T, class ... Ts>
class MyClass {
public:
virtual void hello(const T& t) = 0;
};
would make available the methods hello(const double&) and hello(const int&) when instantiated as MyClass<double, int> myclass;
Note that I want the class to be pure abstract, such that a derived class would actually need to do the implementation, e.g.:
class Derived : MyClass<double, int> {
public:
inline void hello(const double& t) override { }
inline void hello(const int& t) override { }
};
This problem is somewhat similar to this one, but I couldn't understand how to adapt it to my case.
EDIT
The recursion inheritance seems to be the right solution for me. How about this more complicated case, where the superclass has more than one method and a template argument is mandatory? Here is what I've tried (but I get error):
template <class MandatoryT, class OptionalT, class... MoreTs>
class MyClass : public MyClass<MandatoryT, MoreTs...> {
public:
virtual ~MyClass() {}
virtual char* goodmorning(const MandatoryT& t) = 0;
virtual bool bye(const MandatoryT& t,
const std::map<std::string,bool>& t2) = 0;
using MyClass<MandatoryT, MoreTs...>::hello;
virtual void hello(const OptionalT& msg) = 0;
};
template <class MandatoryT, class OptionalT>
class MyClass<MandatoryT, OptionalT> {
virtual void processSecondaryMessage(const OptionalT& msg) = 0;
};
template <class MandatoryT>
class MyClass<MandatoryT> {
virtual void processSecondaryMessage() = 0;
}
}
Basically what I want is that the derived class should have one or more types. The first one is used in other methods, while from the second onwards it should be used in hello(). If only one type is provided, an empty hello() is called. But when at least a second type is provided, hello() should use it.
The code above complains that there should be at least two template arguments, because there are "two" ground cases instead of one.
Maybe someone else can do better, but I see only two ways
Recursion inheritance
You can define MyClass recursively as follows
// recursive case
template <typename T, typename ... Ts>
struct MyClass : public MyClass<Ts...>
{
using MyClass<Ts...>::hello;
virtual void hello (const T&) = 0;
};
// ground case
template <typename T>
struct MyClass<T>
{ virtual void hello (const T&) = 0; };
or
variadic inheritance
You can define another class/struct, say MyHello, that declare a
single hello() method, and variadic inherit it from MyClass.
template <typename T>
struct MyHello
{ virtual void hello (const T&) = 0; };
template <typename ... Ts>
struct MyClass : public MyHello<Ts>...
{ };
The recursive example is compatible with type collision (that is: works also when a type is present more time in the list of template arguments MyClass; by example MyClass<int, double, int>).
The variadic inheritance case, unfortunately, isn't.
The following is a full compiling example
#if 1
// recursive case
template <typename T, typename ... Ts>
struct MyClass : public MyClass<Ts...>
{
using MyClass<Ts...>::hello;
virtual void hello (const T&) = 0;
};
// ground case
template <typename T>
struct MyClass<T>
{ virtual void hello (const T&) = 0; };
#else
template <typename T>
struct MyHello
{ virtual void hello (const T&) = 0; };
template <typename ... Ts>
struct MyClass : public MyHello<Ts>...
{ };
#endif
struct Derived : public MyClass<double, int>
{
inline void hello (const double&) override { }
inline void hello (const int&) override { }
};
int main()
{
Derived d;
d.hello(1.0);
d.hello(2);
}
-- EDIT --
The OP asks
how about a more complicated case where MyClass has more than one method and I always need to have one template argument (see edited question)?
From your question I don't understand what do you exactly want.
But supposing you want a pure virtual method, say goodmorning() that receive a MandT (the mandatory type), a pure virtual method hello() for every type following MandT or an hello() without arguments when the list after MandT is empty.
A possible solution is the following
// declaration and groundcase with only mandatory type (other cases
// intecepted by specializations)
template <typename MandT, typename ...>
struct MyClass
{
virtual void hello () = 0;
virtual ~MyClass () {}
virtual char * goodmorning (MandT const &) = 0;
};
// groundcase with a single optional type
template <typename MandT, typename OptT>
struct MyClass<MandT, OptT>
{
virtual void hello (OptT const &) = 0;
virtual ~MyClass () {}
virtual char * goodmorning (MandT const &) = 0;
};
// recursive case
template <typename MandT, typename OptT, typename ... MoreOptTs>
struct MyClass<MandT, OptT, MoreOptTs...>
: public MyClass<MandT, MoreOptTs...>
{
using MyClass<MandT, MoreOptTs...>::hello;
virtual void hello (OptT const &) = 0;
virtual ~MyClass () {}
};
Here the recursion is a little more complicated than before.
In case you instantiate a MyClass with only the mandatory type (by example: MyClass<char>) the main version ("groundcase with only mandatory type") is selected because the two specialization doesn't match (no first optional type).
In case you instantiate a Myclass with one optional type (say MyClass<char, double>) the specialization "groundcase with a single optional type" is selected because is the most specialized version.
In case you instantiate a MyClass with two or more optional type (say MyClass<char, double, int> start recursion (last specialization) until remain an single optional type (so the "groundcase with a single optional type" is selected).
Observe that I've placed the goodmorning() in both ground cases, because you don't need to define it recursively.
The following is a full compiling example
// declaration and groundcase with only mandatory type (other cases
// intecepted by specializations)
template <typename MandT, typename ...>
struct MyClass
{
virtual void hello () = 0;
virtual ~MyClass () {}
virtual char * goodmorning (MandT const &) = 0;
};
// groundcase with a single optional type
template <typename MandT, typename OptT>
struct MyClass<MandT, OptT>
{
virtual void hello (OptT const &) = 0;
virtual ~MyClass () {}
virtual char * goodmorning (MandT const &) = 0;
};
// recursive case
template <typename MandT, typename OptT, typename ... MoreOptTs>
struct MyClass<MandT, OptT, MoreOptTs...>
: public MyClass<MandT, MoreOptTs...>
{
using MyClass<MandT, MoreOptTs...>::hello;
virtual void hello (OptT const &) = 0;
virtual ~MyClass () {}
};
struct Derived0 : public MyClass<char>
{
void hello () override { }
char * goodmorning (char const &) override
{ return nullptr; }
};
struct Derived1 : public MyClass<char, double>
{
void hello (double const &) override { }
char * goodmorning (char const &) override
{ return nullptr; }
};
struct Derived2 : public MyClass<char, double, int>
{
void hello (double const &) override { }
void hello (int const &) override { }
char * goodmorning (char const &) override
{ return nullptr; }
};
int main()
{
Derived0 d0;
Derived1 d1;
Derived2 d2;
d0.hello();
d0.goodmorning('a');
d1.hello(1.2);
d1.goodmorning('b');
d2.hello(3.4);
d2.hello(5);
d2.goodmorning('c');
}

Why do I need the move constructor, if the constructor take values

I have the following example:
#include <cstdint>
class A
{
public:
A(const A&) = delete;
A& operator = (const A&) = delete;
A(A&&) = default; // why do I need the move constructor
A&& operator = (A&&) = delete;
explicit A(uint8_t Val)
{
_val = Val;
}
virtual ~A() = default;
private:
uint8_t _val = 0U;
};
class B
{
public:
B(const B&) = delete;
B& operator = (const B&) = delete;
B(B&&) = delete;
B&& operator = (B&&) = delete;
B() = default;
virtual ~B() = default;
private:
A _a = A(4U); // call the overloaded constructor of class A
};
int main()
{
B b;
return 0;
}
why do I need the move-constructor "A(A&&) = default;" in A? I could not the code line where the mentioned move-constructor is called.
Many thanks in advance.
A _a = A(4U) in this case depends on the move constructor.
This type of initialization is called copy initialization, and according to the standard it may invoke the move constructor, see 9.3/14.

C++ template deduction couldn't infer template argument

I have the following scenario:
struct AP;
struct B
{
B() : m(2) {}
int m;
};
struct A : private B
{
A() : B(), n(1) {}
private:
int n;
friend AP;
};
struct AP
{
AP(A& a) : a_(a) {}
template<typename T>
struct A_B {
using type = typename std::enable_if< std::is_base_of< typename std::remove_reference<T>::type,
A >::value,
T >::type;
};
template<typename T>
operator typename A_B<T>::type()
{
return static_cast<T>(a_);
}
template<typename T>
typename A_B<T>::type get()
{
return static_cast<T>(a_);
}
int& n() { return a_.n; }
private:
A& a_;
};
int main()
{
A a;
AP ap(a);
ap.n() = 7;
const B& b = ap.get<const B&>();
//const B& b = ap; candidate template ignored: couldn't infer template argument 'T'
//auto b = static_cast<const B&>(ap); candidate template ignored: couldn't infer template argument 'T'
std::cout<<b.m;
}
The commented lines wouldn't compile. Clang++ notes that "candidate template ignored: couldn't infer template argument 'T'"
Why am I not able to get a reference to A's base with the cast operator?
I think the code would look much nicer that way.
The answer that you posted works, but is overkill unless you really want a static_assert message.
Classic templating works just fine in this instance because A is already convertible to B:
struct AP
{
AP(A& a) : a_(a) {}
template<typename T>
operator T()
{
return a_;
}
template<typename T>
T get()
{
return a_;
}
int& n() { return a_.n; }
private:
A& a_;
};
Demo
I found the answer here: http://www.mersenneforum.org/showthread.php?t=18076
This is the key: "when you want the compiler to deduce argument types, those types must not be dependent types"
With this it compiles:
template<typename T>
operator T()
{
static_assert(std::is_base_of< typename std::remove_reference<T>::type,A >::value,
"You may cast AP only to A's base classes.");
return static_cast<T>(a_);
}

Getting weak pointer to derived class

I have a bunch of derived classes stored as shared pointers, I was wondering if there is any way of getting a weak_ptr to the object from inside the object?
I've tried using the shared_from_this() function but the problem is that since it's a derived class, when I make the base class inherit from enable_shared_from_this, when the derived class calls shared_from_this() it gets a shared_ptr of the base class not the derived class which I can't turn into a shared_ptr of the derived class
Any suggestions?
Usign CRTP you can achieve it:
#include <memory>
template<typename T>
struct B: std::enable_shared_from_this<T> {};
struct D: B<D> {};
int main() {
std::shared_ptr<B<D>> b = std::make_shared<D>();
std::shared_ptr<D> d = b->shared_from_this();
std::weak_ptr<D> w = b->shared_from_this();
}
If you want to have a common, non-template base class, you can rely on techniques like the double dispatching, as in the following example:
#include <memory>
#include <iostream>
struct D1;
struct D2;
struct S {
void doSomething(std::weak_ptr<D1> weak) { std::cout << "D1" << std::endl; }
void doSomething(std::weak_ptr<D2> weak) { std::cout << "D2" << std::endl; }
};
struct B: std::enable_shared_from_this<B> {
virtual void dispatch(S &) = 0;
};
template<typename T>
struct M: B {
void dispatch(S &s) override {
auto ptr = std::static_pointer_cast<T>(shared_from_this());
s.doSomething(ptr);
}
};
struct D1: M<D1> {};
struct D2: M<D2> {};
int main() {
std::shared_ptr<B> b = std::make_shared<D1>();
S s;
b->dispatch(s);
}
As #Torbjörn said, using the dynamic_pointer_cast<Derived>(base_ptr) fixed this problem as it allowed me to convert shared_ptr's down in inheritance, something that isn't directly allowed.

Resources