How to disable instantiating a temporary class? - c++14

I'm working with an expression template class which should not be instantiated to avoid dangling references. But I'm temped to declare a variable with auto and 'auto' create a named instance of a temporary class.
How can I disable auto declaration of temporary class in the following code?
class Base
{
};
class Temp : public Base
{
public:
Temp() {}
Temp(int, int) {}
Temp(const Temp&) = default;
Temp(Temp&&) = default;
};
Temp testFunc(int a, int b) {
return Temp{a,b};
}
int main() {
Base a = testFunc(1,2); // this should work
auto b = testFunc(1,2); // this should fail to compile
return 0;
}

You seem to want to prevent users from using auto on a particular type. That's not possible in any version of C++. If it is legal C++ for a user to write T t = <expr>;, where T is the type of <expr>, then it will be legal for a user to write auto t = <expr>; (ignoring class data members). Just as you cannot forbid someone from passing <expr> to a template function using template argument deduction.
Anything you do to prevent auto usage will also inhibit some other usage of the type.

One option would be to make Temp's constructors private, move testFunc inside the Temp class and make it static. This way you can still instantiate Base, but auto would fail because you would be calling a private constructor:
class Base
{
};
class Temp : public Base
{
Temp() {}
Temp(int, int) {}
Temp(const Temp&) = default;
Temp(Temp&&) = default;
public:
static Temp testFunc(int a, int b)
{
return Temp{a,b};
}
};
int main() {
Base a = Temp::testFunc(1,2); // this should work
auto b = Temp::testFunc(1,2); // this should fail to compile
return 0;
}
Demo

Related

Encounter std::bad_weak_ptr exception after converting a unique_ptr created from a factory method to shared_ptr and using shared_from_this

In summary, I have a class inherited from std::enabled_shared_from_this, and there is a factory method return an std::unique_ptr of it. In another class, I convert the std::unique_ptr of the previous class object to std::shared_ptr, and then I call shared_from_this(), which then throws std::bad_weak_ptr. The code is shown below:
#include <memory>
#include <iostream>
struct Executor;
struct Executor1 {
Executor1(const std::shared_ptr<Executor>& executor,
int x): parent(executor) {
std::cout << x << std::endl;
}
std::shared_ptr<Executor> parent;
};
struct Backend {
virtual ~Backend() {}
virtual void run() = 0;
};
struct Executor: public Backend, public std::enable_shared_from_this<Executor> {
const int data = 10;
virtual void run() override {
Executor1 x(shared_from_this(), data);
}
};
// std::shared_ptr<Backend> createBackend() {
std::unique_ptr<Backend> createBackend() {
return std::make_unique<Executor>();
}
class MainInstance {
private:
std::shared_ptr<Backend> backend;
public:
MainInstance(): backend(createBackend()) {
backend->run();
}
};
int main() {
MainInstance m;
return 0;
}
Indeed changing std::unique_ptr<Backend> createBackend() to std::shared_ptr<Backend> createBackend() can solve the problem, but as I understand, in general, the factory pattern should prefer return a unique_ptr. Considering a good pratice of software engineering, is there a better solution?
[util.smartptr.shared.const]/1 In the constructor definitions below, enables shared_from_this with p, for a pointer p of type Y*, means that if Y has an unambiguous and accessible base class that is a specialization of enable_shared_from_this (23.11.2.5), then [magic happens that makes shared_from_this() work for *p - IT]
template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
[util.smartptr.shared.const]/29 Effects: ... equivalent to shared_ptr(r.release(), r.get_deleter())...
template<class Y, class D> shared_ptr(Y* p, D d);
[util.smartptr.shared.const]/10 Effects: ... enable shared_from_this with p
Your example executes std::shared_ptr<Backend>(uptr) where uptr is std::unique_ptr<Backend>, which is equivalent to std::shared_ptr<Backend>(p, d) where p is of type Backend*. This constructor enables shared_from_this with p - but that's a no-op, as Backend doesn't have an unambiguous and accessible base class that is a specialization of enable_shared_from_this
In order for Executor::enable_from_this to work, you need to pass to a shared_ptr constructor a pointer whose static type is Executor* (or some type derived therefrom).
Ok, I find a simple solution, that is, using auto as the return type of the factory function, instead of std::unique_ptr or std::shared_ptr, and keeping std::make_unique inside the factory function. The factory function createBackend should be:
auto createBackend() {
return std::make_unique<Executor>();
}
In this case, the return type can be automatically determined, although I don't know how it works exactly. This code can return either unique_ptr or shared_ptr, which should be better than just using shared_ptr. I tested clang and gcc, and both of them worked, but I am still not sure if this is gauranteed by the type deduction and the implicit conversion.
Update:
Actually, I have found that auto deduces the return type above as std::unique_ptr<Executor> instead of std::unique_ptr<Backend>, which might be the reason why the code works. But using auto has an issue: if you return the smart pointer in an if-else block, where the return type varies depending on some parameters, then auto cannot determine the type. For example:
std::unique_ptr<Backend> createBackend(int k = 0) {
if (k == 0) {
return std::make_unique<Executor>();
}
else {
return std::make_unique<Intepreter>();
}
}
Here, both Executor and Intepreter derive from Backend. I think a correct solution includes:
Inherit Backend instead of its derived classes from std::enable_shared_from_this;
Use dynamic_pointer_cast<Derived class> to cast the shared_ptr to derived class after shared_from_this.
The full code is listed in:
https://gist.github.com/HanatoK/8d91a8ed71271e526d9becac0b20f758

Can a method of an class (in a shared_ptr) be tied to a static function in a traits class?

Historically, I've been using trait classes to hold information and apply that into a "generic" function that runs the same "algorithm." Only differed by the trait class. For example: https://onlinegdb.com/ryUo7WRmN
enum selector { SELECTOR1, SELECTOR2, SELECTOR3, };
// declaration
template < selector T> struct example_trait;
template<> struct example_trait<SELECTOR1> {
static constexpr size_t member_var = 3;
static size_t do_something() { return 0; }
};
template<> struct example_trait<SELECTOR2> {
static constexpr size_t member_var = 5;
static size_t do_something() { return 0; }
};
// pretend this is doing something useful but common
template < selector T, typename TT = example_trait<T> >
void function() {
std::cout << TT::member_var << std::endl;
std::cout << TT::do_something() << std::endl;
}
int main()
{
function<SELECTOR1>();
function<SELECTOR2>();
return 0;
}
I'm not sure how to create "generic" algorithms this when dealing with polymorphic classes.
For example: https://onlinegdb.com/S1hFLGC7V
Below I have created an inherited class hierarchy. In this example I have a base catch-all example that defaults all the parameters to something (0 in this case). And then each derived class sets overrides specific methods.
#include <iostream>
#include <memory>
#include <type_traits>
#include <assert.h>
using namespace std;
struct Base {
virtual int get_thing_one() {
return 0;
}
virtual int get_thing_two() {
return 0;
}
virtual int get_thing_three() {
return 0;
}
virtual int get_thing_four() {
return 0;
}
};
struct A : public Base {
virtual int get_thing_one() override {
return 1;
}
virtual int get_thing_three() override {
return 3;
}
};
struct B : public Base {
virtual int get_thing_one() override {
return 2;
}
virtual int get_thing_four() override{
return 4;
}
};
Here I created a simple factory, not elegant but for illustrative purposes
// example simple factory
std::shared_ptr<Base> get_class(const int input) {
switch(input)
{
case 0:
return std::shared_ptr<Base>(std::make_shared<A>());
break;
case 1:
return std::shared_ptr<Base>(std::make_shared<B>());
break;
default:
assert(false);
break;
}
}
So this is the class of interest. It is a class does "something" with the data from the classes above. The methods below are a simple addition example but imagine a more complicated algorithm that is very similar for every method.
// class that uses the shared_ptr
class setter {
private:
std::shared_ptr<Base> l_ptr;
public:
setter(const std::shared_ptr<Base>& input):l_ptr(input)
{}
int get_thing_a()
{
return l_ptr->get_thing_one() + l_ptr->get_thing_two();
}
int get_thing_b()
{
return l_ptr->get_thing_three() + l_ptr->get_thing_four();
}
};
int main()
{
constexpr int select = 0;
std::shared_ptr<Base> example = get_class(select);
setter l_setter(example);
std::cout << l_setter.get_thing_a() << std::endl;
std::cout << l_setter.get_thing_b() << std::endl;
return 0;
}
How can I make the "boilerplate" inside the setter class more generic? I can't use traits as I did in the example above because I can't tie static functions with an object. So is there a way to make the boilerplate example more common?
Somewhere along the lines of having a selector, say
enum thing_select { THINGA, THINGB, };
template < thing_select T >
struct thing_traits;
template <>
struct thing_traits<THINGA>
{
static int first_function() --> somehow tied to shared_ptr<Base> 'thing_one' method
static int second_function() --> somehow tied to shared_ptr<Base> 'thing_two' method
}
template <>
struct thing_traits<THINGB>
{
static int first_function() --> somehow tied to shared_ptr<Base> 'thing_three' method
static int second_function() --> somehow tied to shared_ptr<Base> 'thing_four' method
}
// generic function I'd like to create
template < thing_select T, typename TT = thing_traits<T> >
int perform_action(...)
{
return TT::first_function(..) + TT::second_function(..);
}
I ideally would like to modify the class above to something along the lines of
// Inside setter class further above
int get_thing_a()
{
return perform_action<THINGA>(...);
}
int get_thing_b()
{
return perform_action<THINGB>(...);
}
The answer is, maybe I can't, and I need to pass int the shared_ptr as a parameter and call the specific methods I need instead of trying to tie a shared_ptr method to a static function (in hindsight, that doesn't sound like a good idea...but I wanted to bounce my idea)
Whoever makes the actual call will need a reference of the object, one way or the other. Therefore, assuming you want perform_action to perform the actual call, you will have to pass the parameter.
Now, if you really want to store which function of Base to call as a static in thing_traits without passing a parameter, you can leverage pointer to member functions:
template <>
struct thing_traits<THINGA>
{
static constexpr int (Base::*first_function)() = &Base::get_thing_one;
...
}
template < thing_select T, typename TT = thing_traits<T>>
int perform_action(Base & b)
{
return (b.*TT::first_function)() + ...;
}
You can also play instead with returning a function object that does the call for you (and the inner function takes the parameter).
It all depends on who you need to make the call and what information/dependencies you assume you have available in each class/template.

C++ wrapper pass pointer address to native class

Hello I am trying to pass a pointer address from a managed class to an unmanaged
class. So every A-Object has a reference to a B-object. But if I pass the reference in _a = new A(_managedB->_b) the compiler throws an error that no constructor matches the argument list.
So what's wrong with the code?
unmanaged code:
class A
{
private:
B &b;
public:
explicit
A(B& b);
~A();
}
managed code:
public ref class ManagedA
{
private:
ManagedB ^_managedB;
A *_a;
public:
ManagedA::ManagedA(ManagedB ^managedB ): _managedB(managedB)
{
_a = new A(_managedB->_b);
}
ManagedA::~ManagedA(ManagedB ^managedB ): _managedB(managedB)
{
delete _a;
_a = 0;
}
};
Ok I did it like this and it worked.
I don't know if the situation is interpreted right, but I am not trying to pass a Handle as a pointer. I pass a pointer that is a member of an Handle.
public ref class ManagedA
{
private:
ManagedB ^_managedB;
A *_a;
public:
ManagedA::ManagedA(ManagedB ^managedB ): _managedB(managedB)
{
_a = new A(*_managedB->_b);
}
ManagedA::~ManagedA(ManagedB ^managedB ): _managedB(managedB)
{
delete _a;
_a = 0;
}
};

How to make sure your object is zero-initialized?

Update: I'm looking to see if there's a way to zero-initialize the entire class at once, because technically, one can forget adding a '= 0' or '{}' after each member. One of the comments mentions that an explicitly defaulted no-arg c-tor will enable zero-initialization during value-initialization of the form MyClass c{};. Looking at http://en.cppreference.com/w/cpp/language/value_initialization I'm having trouble figuring out which of the statements specify this.
Initialization is a complex topic now since C++11 has changed meaning and syntax of various initialization constructs. I was unable to gather good enough info on it from other questions. But see, for example, Writing a Default Constructor Forces Zero-Initialization?.
The concrete problem I'm facing is: I want to make sure members of my classes are zeroed out both for (1) classes which declare a default c-tor, and for (2) those which don't.
For (2), initializing with {} does the job because it's the syntax for value-initialization, which translates to zero-initialization, or to aggregate initialization if your class is an aggregate - case in which members for which no initializer was provided (all!) are zero-initialized.
But for (1) I'm still not sure what would be the best approach. From all info I gather I learned that if you provide a default c-tor (e.g. for setting some of the members to some values), you must explicitly zero remaining members, otherwise the syntax MyClass c = MyClass(); or the C++11 MyClass c{}; will not do the job. In other words, value-initialization in this case means just calling your c-tor, and that's it (no zero-ing).
You run into the same situation if you declare a c-tor that takes values, and sets those values to a subset of the members, but you'd like other members to be zero-ed: there is no shorthand for doing it - I'm thinking about 3 options:
class MyClass
{
int a;
int b;
int c;
MyClass(int a)
{
this->a = a;
// now b and c have indeterminate values, what to do? (before setting 'a')
// option #1
*this = MyClass{}; // we lost the ability to do this since it requires default c-tor which is inhibited by declaring this c-tor; even if we declare one (private), it needs to explicitly zero members one-by-one
// option #2
std::memset(this, 0, sizeof(*this)); // ugly C call, only works for PODs (which require, among other things, a default c-tor defaulted on first declaration)
// option #3
// don't declare this c-tor, but instead use the "named constructor idiom"/factory below
}
static MyClass create(int a)
{
MyClass obj{}; // will zero-initialize since there are no c-tors
obj.a = a;
return obj;
}
};
Is my reasoning correct?
Which of the 3 options would you choose?
What about using in-class initialization?
class Foo
{
int _a{}; // zero-it
int _b{}; // zero-it
public:
Foo(int a): _a(a){} // over-rules the default in-class initialization
};
Option 4 and 5:
option 4:
MyClass(int a) :a(a), b(0), c(0)
{
}
option 5:
class MyClass
{
int a = 0;
int b = 0;
int c = 0;
MyClass(int a) : a(a) {
}
}
In my humble opinion, the simplest way to ensure zero-initialization is to add a layer of abstraction:
class MyClass
{
struct
{
int a;
int b;
int c;
} data{};
public:
MyClass(int a) : data{a} {}
};
Moving the data members into a struct lets us use value-initialization to perform zero-initialization. Of course, it is now a bit more cumbersome to access those data members: data.a instead of just a within MyClass.
A default constructor for MyClass will perform zero-initialization of data and all its members because of the braced-initializer for data. Additionally, we can use aggregate-initialization in the constructors of MyClass, which also value-initializes those data members which are not explicitly initialized.
The downside of the indirect access of the data members can be overcome by using inheritance instead of aggregation:
struct my_data
{
int a;
int b;
int c;
};
class MyClass : private my_data
{
MyClass() : my_data() {}
public:
MyClass(int a) : MyClass() { this->a = a; }
};
By explicitly specifying the base-initializer my_data(), value-initialization is invoked as well, leading to zero-initialization. This default constructor should probably be marked as constexpr and noexcept. Note that it is no longer trivial. We can use initialization instead of assignment by using aggregate-initialization or forwarding constructors:
class MyClass : private my_data
{
public:
MyClass(int a) : my_data{a} {}
};
You can also write a wrapper template that ensures zero-initialization, thought the benefit is disputable in this case:
template<typename T>
struct zero_init_helper : public T
{
zero_init_helper() : T() {}
};
struct my_data
{
int a;
int b;
int c;
};
class MyClass : private zero_init_helper<my_data>
{
public:
MyClass(int a) { this->a = a; }
};
Having a user-provided constructor, zero_init_helper no longer is an aggregate, hence we cannot use aggregate-initialization any more. To use initialization instead of assignment in the ctor of MyClass, we have to add a forwarding constructor:
template<typename T>
struct zero_init_helper : public T
{
zero_init_helper() : T() {}
template<typename... Args>
zero_init_helper(Args&&... args) : T{std::forward<Args>(args)...} {}
};
class MyClass : private zero_init_helper<my_data>
{
public:
MyClass(int a) : zero_init_helper(a) {}
};
Constraining the constructor template requires some is_brace_constructible trait, which is not part of the current C++ Standard. But this already is a ridiculously complicated solution to the problem.
It is also possible to implement your option #1 as follows:
class MyClass
{
int a;
int b;
int c;
MyClass() = default; // or public, if you like
public:
MyClass(int a)
{
*this = MyClass{}; // the explicitly defaulted default ctor
// makes value-init use zero-init
this->a = a;
}
};
What about constructor delegation?
class MyClass
{
int a;
int b;
int c;
MyClass() = default; // or public, if you like
public:
MyClass(int a) : MyClass() // ctor delegation
{
this->a = a;
}
};
[class.base.init]/7 suggests that the above example shall invoke value-initialization, which leads to zero-initialization since the class does not have any user-provided default constructors [dcl.init]/8.2. Recent versions of clang++ seem to zero-initialize the object, recent versions of g++ do not. I've reported this as g++ bug #65816.

C++11 move assignment operator for classes with objects as members - Beginner Level

I have a beginner question on the move assigment in c++11. Let say that I have a class A provided with a move assigment operator:
class A
{
public:
A();
~A();
A& operator=(A&&);
...
}
I also have a class B containing a class A object and provided with a move assignment operator
class B
{
public:
B();
~B();
B& operator=(B&&);
...
private:
A Test;
}
What I was thinking is that the B move assignment operator will call the move assignment operator of its member so I tried this method:
B& B::operator=(B&& Other)
{
...
Test = Other.Test;
...
return *this;
}
But this is not working since the move assignment of class A is not called.
Instead I was able to make the program work by using this method:
B& B::operator=(B&& Other)
{
...
Test = std::move(Other.Test);
...
return *this;
}
I do not understand why the first method is not working. I was thinking that since a constructor will call its members constructors the move assignment operator should do the same. Am I wrong or I made a mistake in my code? Can someone explain, thanks!
Other.Test is not an rvalue expression since it has a name. OTOH std::move(Other.Test) has the type A and the value category xvalue (i.e., an rvalue). Thus, it can bind to the move constructor.
(EDIT : Shamelessly copied #dyp's comment. Thanks, #dyp and #KerrekSB.)
#Pradhan is correct - you need to use std::move to move the members in the implementation of the move assignment operator. However, if that is all that is needed to implement your move constructor, then you can declare the operator to use the default implementation:
#include <memory>
class A {
public:
A() : p{} { }
~A() { }
A &operator=(A &&) = default;
// Instead of:
// A &operator=(A &&other) {
// p = std::move(other.p);
// return *this;
// }
private:
std::unique_ptr<int> p;
};
int main() {
A a;
A b;
b = std::move(a);
return 0;
}

Resources