Search code examples
c++pass-by-referencervalue-reference

Method for preventing passing temporaries as const reference that scales better then deleting the r-value overload


When one wants to prevent someone passing a temporary as const reference one can delete the r-value overload:

class Foo
{
public:

    Foo(const Bar& bar) : mBar(&bar) {} 
    Foo(const Bar&&) = delete;

private:

    const Bar* mBar;
};

However, when there's multiple such parameters this method does not scale well. It requires deleting every possible combination to be effective:

Foo(const Bar&&, const Baz&, const Qux&) = delete;
Foo(const Bar&, const Baz&&, const Qux&) = delete; 
Foo(const Bar&, const Baz&, const Qux&&) = delete;
Foo(const Bar&&, const Baz&&, const Qux&) = delete;
//And every other combination...

Are there methods that scale better then this?


Solution

  • Something like this maybe? It makes it very clear that you don't want an rvalue, as well.

    struct Foo{};
    template <typename T>
    struct NoRvalue {
        T t;
        NoRvalue(T & t);
        NoRvalue(T&& t) = delete;
    };
    
    void call_me(NoRvalue<Foo> a, NoRvalue<Foo> b);
    void call_me2(Foo const & a, Foo const & b);
    
    int main() {
        Foo f;
        call_me2(f, Foo());
        call_me(f, Foo()); // fails
    }
    

    live: https://godbolt.org/z/LT9iSw