Am I dealing with dangling references?

By defining methods of a class &&, and chaining the calls, am I dealing with dangling references??


My class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
template<typename ConcreteBuilder>
class GenericItemBuilder
{
protected:
	Item item;
public:
	explicit GenericItemBuilder(std::string name) : item{.name = std::move(name)} {}

	Item build() &&
	{
		item.date_added = system_clock::now();
		return std::move(item);
	}
	ConcreteBuilder&& with_description(std::string description) &&
	{
		item.description = description;
		return static_cast<ConcreteBuilder&&>(*this);
	}
	ConcreteBuilder&& marked_as_featured() &&
	{
		item.featured = true;
		return static_cast<ConcreteBuilder&&>(*this);
	}
	ConcreteBuilder&& with_price(float price) &&
	{
		item.price   = price;
		return static_cast<ConcreteBuilder&&>(*this);
	}

};
class ItemBuilder final : public GenericItemBuilder<ItemBuilder>
{
	using GenericItemBuilder<ItemBuilder>::GenericItemBuilder;
};


when called like this:

1
2
3
4
5
void useGenericItemBuilder()
{
	auto directly_loaded_item = ItemBuilder{ "Pot" }.with_description("A decent one").with_price(100).build();

}





Regards


Move-constructing an object, from an r-value reference, never leaves you with a "dangling" reference. Instead, even though the move-constructor is allowed to "steal" the resources from the "moved from" object (instead of having to copy them), still the "moved from" object will be left in an undefined but valid state!
Last edited on
Am I introducing temporary objects with this code? Should I remove the && on methods?

Is this code in danger of a dangling reference?
Last edited on
By using the && ref-qualifier on a member function, you are telling the compiler that this function is supposed to be called on an r-value reference. An r-value reference allows the move-constructor to be called, instead of the copy-constructor. But, as said before, the move-constructor does not produce "dangling" references.

(after move-construction, the "moved from" object is left in a undefined but valid state)

Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
class Foo
{
public:
    Foo(const int value)
    {
        std::cout << "Constructor" << std::endl;
        data = new int { value };
    }

    Foo(const Foo &other)
    {
        std::cout << "Copy constructor" << std::endl;
        data = new int { *other.data };
    }

    Foo(Foo &&other)
    {
        std::cout << "Move constructor" << std::endl;
        data = other.data;
        other.data = NULL;
    }

    Foo test(void) &
    {
        std::cout << "test(void) &" << std::endl;
        return Foo(*this);
    }

    Foo test(void) &&
    {
        std::cout << "test(void) &&" << std::endl;
        return Foo(std::move(*this));
    }

    int value(void)
    {
        return data ? (*data) : (-1);
    }

protected:
    int *data;
};

int main()
{
    Foo foo(42);

    std::cout << "---" << std::endl;

    std::cout << foo.test().value() << std::endl;
    std::cout << foo.value() << std::endl;

    std::cout << "---" << std::endl;

    std::cout << std::move(foo).test().value() << std::endl;
    std::cout << foo.value() << std::endl;

    std::cout << "---" << std::endl;

    std::cout << Foo(42).test().value() << std::endl;
}

Constructor
---
test(void) &
Copy constructor
42
42
---
test(void) &&
Move constructor
42
-1
---
Constructor
test(void) &&
Move constructor
42
Last edited on
The method && mean that the member function can only be invoked on r-values (the && applies to this - similar to how const applies to this). This allows multiple member-function overloads based upon these ref-qualifies (const, &, &&) with different code/return for each.

However, you probably shouldn't use std::move() on L12. This can break return value optimisation (copy elision etc).
Last edited on
std::move() is required; copy elision can't be applied to member objects.
Topic archived. No new replies allowed.