Is there a way to check if RVO was applied? - c++11

I had this whole story about my frustrating journey to finding out that an unordered map I was returning from a function was not in fact RVO'd even though I was certain it was at an earlier time that it was but irrelevant.
Is there a way to check if RVO is happening in any given function? Or like a list of do's and dont's to follow to get the outcome I desire?

Yes. Create hooks for the lifecycle methods of your class:
#include <iostream>
struct A{
A()
{ std::cout<<"Ctor\n"; }
A(const A& o)
{ std::cout<<"CCtor\n"; }
A(A&& o)
{ std::cout<<"MCtor\n"; }
~A()
{ std::cout<<"Dtor\n"; }
private:
int vl_;
};
A getA(){
A a;
return a;
}
int main(){
A b = getA();
return 0;
}
Now with RVO, b is the same object as a in getA so you'll only see
Ctor
Dtor
You can suppress RVO, e.g., by adding an additional return point:
return a;
return A{a};
or moving:
return std::move(a);
And then you'll see:
Ctor
Mctor
Dtor
Dtor

You can verify that RVO was used in all the places where it's important to you:
template<typename T>
struct force_rvo: T {
force_rvo() {}
using T::T;
force_rvo(const force_rvo &);
force_rvo(force_rvo &&);
};
force_rvo<std::map<int, int>> f() {
force_rvo<std::map<int, int>> m;
m[17] = 42;
return m;
}
int main() {
auto m = f();
return m[42];
}
The force_rvo type pretends to be copyable and movable, otherwise compiler would reject return m. But if any of these is actually used, linker will fail and tell you where exactly that happened. The wrapper is zero cost, but requires using it both on caller and implementation sides, which may not be very convenient.

Related

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.

Is it possible to have a copy constructible class that holds a std::unique_ptr<Base> avoiding slicing without Base exposing a "clone" function?

Is there a way to write a copy-constructor for a class (say, Copyable, that holds a std::unique_ptr to a Base class (but really is storing Derived objects.
A quick test shows the expected slicing occurs, because Copyable doesn't know the real type it's holding. So I suppose a clone method is needed, but I'm wondering if there is a way to let the compiler handle this in some better way?
The slicing code:
#include <algorithm>
#include <iostream>
#include <memory>
struct Base
{
Base(int i = 0) : i(i) {}
virtual ~Base() = default;
int i;
virtual int f() { return i; }
};
struct Derived : Base
{
Derived() = default;
virtual int f() override { return 42; }
};
struct Copyable
{
Copyable(std::unique_ptr<Base>&& base) : data(std::move(base)) {}
Copyable(const Copyable& other)
{
data = std::make_unique<Base>(*other.data);
}
std::unique_ptr<Base> data;
};
int main()
{
Copyable c(std::make_unique<Derived>());
Copyable c_copy = c;
std::cout << c_copy.data->f() << '\n';
}
The clone code:
#include <algorithm>
#include <iostream>
#include <memory>
struct Base
{
Base(int i = 0) : i(i) {}
virtual ~Base() = default;
int i;
virtual int f() { return i; }
virtual Base* clone() { return new Base(i); }
};
struct Derived : Base
{
Derived() = default;
virtual int f() override { return 42; }
virtual Derived* clone() override { return new Derived(); }
};
struct Copyable
{
Copyable(std::unique_ptr<Base>&& base) : data(std::move(base)) {}
Copyable(const Copyable& other)
{
data.reset(other.data->clone());
}
std::unique_ptr<Base> data;
};
int main()
{
Copyable c(std::make_unique<Derived>());
Copyable c_copy = c;
std::cout << c_copy.data->f() << '\n';
}
Obviously the clone code works. Thing is, there's some things in it I'd like to avoid:
raw new.
a random function that needs to be part of the interface.
This function returns a raw pointer.
Every user of this class that wants to be copyable needs to call this function.
So, is there a "clean" alternative?
Note I want to use smart pointers for all the obvious reasons, I just need a deep copying std::unique_ptr. Something like std::copyable_unique_ptr, combining optional move semantics with a deep copying copy constructor. Is this the cleanest way? Or does that only add the the confusion?
You can certainly create a clone_ptr-class for any object you know statically how to clone.
It would hold a pointer to the object, and a pointer to a function for cloning said object, probably from converting a stateless lambda.

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;
}

Is there a better way in C++11 to construct classes on the stack

If I have two classes D1 and D2 that both derive from class Base, and I want to construct a particular one based on say, a boolean variable, there are various well known techniques, eg use a factory, or use smart pointers.
For example,
std::unique_ptr<Base> b;
if (flag)
{
b.reset(new D1());
}
else
{
b.reset(new D2());
}
But this uses the heap for allocation, which is normally fine but I can think of times where it would be good to avoid the performance hit of a memory allocation.
I tried:
Base b = flag ? D1() : D2(); // doesn’t compile
Base& b = flag ? D1() : D2(); // doesn’t compile
Base&& b = flag ? D1() : D2(); // doesn’t compile
Base&& b = flag ? std::move(D1()) : std::move(D2()); // doesn’t compile
My intention is that D1 or D2 whichever is chosen is constructed on the stack, and its lifetime ends when b goes out of scope. Intuitively, I feel there should be a way to do it.
I played with lambda functions and found that this works:
Base&& b = [j]()->Base&&{
switch (j)
{
case 0:
return std::move(D1());
default:
return std::move(D2());
}
}();
Why it doesn’t suffer from the same issues as the others that do not compile I do not know.
Further, it would only be suitable for classes that are inexpensive to copy, because despite my explicit request to use move, it does I think still call a copy constructor. But if I take away the std::move, I get a warning!
I feel this is closer to what i think should be possible but it still has some issues:
the lambda syntax is not friendly to old-timers who havent yet
embraced the new features of the language ( myself included)
the copy constructor call as mentioned
Is there a better way of doing this?
If you know all the types, you can use a Boost.Variant, as in:
class Manager
{
using variant_type = boost::variant<Derived1, Derived2>;
struct NameVisitor : boost::static_visitor<const char*>
{
template<typename T>
result_type operator()(T& t) const { return t.name(); }
};
public:
template<typename T>
explicit Manager(T t) : v_(std::move(t)) {}
template<typename T>
Manager& operator=(T t)
{ v_ = std::move(t); return *this; }
const char* name()
{ return boost::apply_visitor(NameVisitor(), v_); }
private:
variant_type v_;
};
Note: by using variant, you no longer need a base class or virtual functions.
The way you are trying to do it, you are going to get a dangling reference. Having the std::move is just hiding that.
Generally I just structure the code so that the logic is in a separate function. That is, instead of
void f(bool flag)
{
Base &b = // some magic to choose which derived class to instantiate
// do something with b
}
I do
void doSomethingWith(Base &b)
{
// do something with b
}
void f(bool flag)
{
if (flag) {
D1 d1;
doSomethingWith(d1);
}
else {
D2 d2;
doSomethingWith(d2);
}
}
However, if that doesn't work for you, you can use a union inside a class to help manage it:
#include <iostream>
using std::cerr;
struct Base {
virtual ~Base() { }
virtual const char* name() = 0;
};
struct Derived1 : Base {
Derived1() { cerr << "Constructing Derived1\n"; }
~Derived1() { cerr << "Destructing Derived1\n"; }
virtual const char* name() { return "Derived1"; }
};
struct Derived2 : Base {
Derived2() { cerr << "Constructing Derived2\n"; }
~Derived2() { cerr << "Destructing Derived2\n"; }
virtual const char* name() { return "Derived2"; }
};
template <typename B,typename D1,typename D2>
class Either {
union D {
D1 d1;
D2 d2;
D() { }
~D() { }
} d;
bool flag;
public:
Either(bool flag)
: flag(flag)
{
if (flag) {
new (&d.d1) D1;
}
else {
new (&d.d2) D2;
}
}
~Either()
{
if (flag) {
d.d1.~D1();
}
else {
d.d2.~D2();
}
}
B& value()
{
if (flag) {
return d.d1;
}
else {
return d.d2;
}
}
};
static void test(bool flag)
{
Either<Base,Derived1,Derived2> either(flag);
Base &b = either.value();
cerr << "name=" << b.name() << "\n";
}
int main()
{
test(true);
test(false);
}
gives this output:
Constructing Derived1
name=Derived1
Destructing Derived1
Constructing Derived2
name=Derived2
Destructing Derived2
You can ensure you have enough space for allocating either on the stack with std::aligned_storage. Something like:
// use macros for MAX since std::max is not const-expr
std::aligned_storage<MAX(sizeof(D1), sizeof(D2)), MAX(alignof(D1), alignof(D2))> storage;
Base* b = nullptr;
if (flag)
b = new (&storage) D1();
else
b = new (&storage) D2();
You can make a wrapper type for aligned_storage that just takes two types and does the maximum of size/alignment of the two without needing to repeat yourself in the code using it. You can emulate aligned_storage for non-over-aligned types fairly trivially too if you need C++98 support. The custom type without over-aligned support would be something like:
template <typename T1, typename T2>
class storage
{
union
{
double d; // to force strictest alignment (on most platforms)
char b[sizeof(T1) > sizeof(T2) ? sizeof(T1) : sizeof(T2)];
} u;
};
And that can be given protections against copies/moves if you so wish. It can even be turned into a simplified Boost.Variant with relatively little work.
Note that with this approach (or some of the others), destructors will not be called automatically on your class and you must call them yourself. If you want RAII patterns to apply here, you can extend the example class above to store a deleter function that is bound during construction into the space.
template <typename T1, typename T2>
class storage
{
using deleter_t = void(*)(void*);
std::aligned_storage<
sizeof(T1) > sizeof(T2) ? sizeof(T1) : sizeof(T2),
alignof(T1) > alignof(T2) ? alignof(T1) : alignof(T2)
> space;
deleter_t deleter = nullptr;
public:
storage(const storage&) = delete;
storage& operator=(const storage&) = delete;
template <typename T, typename ...P>
T* emplace(P&&... p)
{
destroy();
deleter = [](void* obj){ static_cast<T*>(obj)->~T(); }
return new (&space) T(std::forward<P>(p)...);
}
void destroy()
{
if (deleter != nullptr)
{
deleter(&space);
deleter = nullptr;
}
}
};
// usage:
storage<D1, D2> s;
B* b = flag ? s.emplace<D1>() : s.emplace<D2>();
And of course that can all be done in C++98, just with a lot more work (especially in terms of emulating the emplace function).
How about
B&&b = flag ? static_cast<B&&>(D1()) : static_cast<B&&>(D2());
If you just need them to be freed when the reference goes out of scope, you could implement another simple class (maybe named DestructorDecorator) that points to the object (D1 or D2). And then you just have to implement ~DestructorDecorator to call the destructor of D1 or D2.
You haven't mentioned it, your flag is known at compile time?
As far as a compile-time flag is concerned, you can use template magic to deal with the conditional construction of the class:
First, declaring a template create_if which takes two types and a boolean:
template <typename T, typename F, bool B> struct create_if {};
Second, specializing create_if for true and false values:
template <typename T, typename F> struct create_if<T, F, true> { using type = T; };
template <typename T, typename F> struct create_if<T, F, false> { using type = F; };
Then, you can do this:
create_if<D1, D2, true>::type da; // Create D1 instance
create_if<D1, D2, false>::type db; // Create D2 instance
You can change the boolean literals with your compile-time flag or with a constexpr function:
constexpr bool foo(const int i) { return i & 1; }
create_if<D1, D2, foo(100)>::type dc; // Create D2 instance
create_if<D1, D2, foo(543)>::type dd; // Create D1 instance
This is valid only if the flag is known at compile time, I hope it helps.
Live example.

Why does GCC not find my non-template function? ("no matching function for call to...")

In MSVC 2008, I have the following code:
class Foo {
// Be a little smarter about deriving the vertex type, to save the user some typing.
template<typename Vertex> inline void drawVertices(
Elements vCount, RenPrim primitiveType, PixMaterial *mtl, Vertex const *vertices)
{
this->drawVertices(vCount, primitiveType, mtl, vertices, Vertex::VertexType);
}
virtual void drawVertices(
Elements vCount,
RenPrim primitiveType,
PixMaterial *mtl,
void const *vertices,
uint vertexType) = 0;
};
I use it something like:
struct RenFlexibleVertexPc
{
enum { VertexType = RenVbufVertexComponentsPc };
float x;
float y;
float z;
GraVideoRgba8 c; // Video format, not external!
};
PixMaterial *material;
struct Pc : RenFlexibleVertexPc
{
void set(Triple t, uint cl) { x = (float)t.x_; y = (float)t.y_; z = (float)t.z_; c = cl; }
} vpc[4];
...
Foo *renderer;
renderer->drawVertices(4, RenPrimTriangleFan, material, vpc);
This works fine in MSVC 2008 SP1. However, GCC (3.4 and 4.1,2) throws a "no matching function for call to function" error, apparently not seeing the template when there is a non-template function with more arguments.
Is GCC broken, or is my code broken, and if so, why?
There is no problem with overloading or inheritance:
#include <iostream>
#include <memory>
namespace {
struct A {
virtual void f()
{
std::cout<<"inside A's f()\n";
}
template <typename T> void f(T t)
{
std::cout<<T::i<<'\t';
this->f();
}
};
struct B : A {
void f()
{
std::cout<<"hello\t";
A::f();
}
};
struct C {
static const unsigned int i = 5;
};
struct D {
enum { i = 6 };
};
}
int main()
{
std::auto_ptr<A> b(new B());
b->f(C());
b->f(D());
}
Works correctly. On the other hand, the smallest example I can find that exhibits your problem does not have inheritance or overloading:
#include <iostream>
namespace {
struct A {
template<class C> void print(C c)
{
c.print();
}
};
}
int main()
{
struct B {
void print()
{
std::cout << "whee!\n";
}
};
A a;
B b;
a.print(b);
}
Note that if struct B is defined in a namespace (whether it's an unnamed namespace, or a completely different namespace, or the global namespace) instead of inside main() that this compiles without error.
I don't know enough of the standard to say if this is a bug, but it appears to be one. I've gone ahead and reported it to the GCC bug database.
And here's your answer from the GCC developers (from the link above): "Local classes cannot be template arguments."
So the code is broken. Not that it's a bad idea. In fact, C++0x removes this restriction.
I noticed the line
Note that the code works in GCC if I explicitly cast vpc to (RenFlexibleVertexPc *)
And since RenFlexibleVertexPc is not a local class this makes sense. However Pc is a local class/struct, so it is not allowed.
#OP: Specifying the template parameter is a valid approach.
renderer->drawVertices<RenFlexibleVertexPc>(4, RenPrimTriangleFan, material, vpc);
With Pete's additions, you code also compiles on Apple's GCC 4.0.1, so I suspect there's something your posted code is missing that's causing the problem.
#Max: GCC's treatment of your source is standard. Struct B is local to main(), so B (and thus main()::B::print()) is not visible outside main(). As you're probably aware, moving the definition of B outside of main() and it will compile.
The definition of VertexType is already in the code (an enum). Elements is an unsigned long. Note that the code works in GCC if I explicitly cast vpc to (RenFlexibleVertexPc *)
If it's an enum why pass an object of type array 4 of struct? What is RenFlexibleVertexPc? The last argument to drawVertices should either be a constant pointer to a Vertex object or a const* to an object of a class derived from Vertex.
Foo *renderer;
renderer->drawVertices(4, RenPrimTriangleFan, material, vpc);
You are calling a function on an uninitialized pointer. I hope this is not the real code. \

Resources