vendredi 28 décembre 2018

Can a class object be created as an lvalue-only?

A well-known problem with std::lock_guard (and its relatives) is that it does not work the way as expected when only a temporary object is created.

For example:

std::mutex mtx;

std::lock_guard<std::mutex> {mtx} // temporary object, does not lock the entire scope

std::lock_guard<std::mutex> lck{mtx} // correct

I tried reference qualifiers to create a replacement that prevents a temporary object from being created (at compile time). The following code is a futile attempt:

#include <mutex>

template<typename T>
struct my_lock {
    T &mtx;
    my_lock(T &t) : mtx{t} { lock(); }
    ~my_lock() { unlock(); }

    void lock() & { mtx.lock(); };
    void unlock() & { mtx.unlock(); };
};


std::mutex mtx;

int main()
{
    my_lock<std::mutex> {mtx}; // A 

    my_lock<std::mutex lck{mtx}; // B
}

This does not work, so the question becomes:

Is it possible to write the class in such a way that the compiler rejects A and accepts B ?

Aucun commentaire:

Enregistrer un commentaire