Date: Thu, 5 Oct 2017 13:31:18 +0300
It occurs to me that it would be useful to have a feature macro for
mandatory copy elision. This came up
in Qt: https://codereview.qt-project.org/#/c/206467/
So, we want to have a RAII handle that should not easily traverse
scopes. Since the RAII handle
wishes to store an arbitrary functor, we need to make it a template.
In order to avoid having to
force users to specify complex template arguments, we want to add a
factory function (we could
use Class Template Argument Deduction but that's another thing with
another macro). For C++17,
the factory can just return a noncopyable nonmovable type. For earlier
versions, we can befriend
the factory and require that users use lifetime-extending references
for the factory's return value.
With the envisioned macro, the class would look roughly like this,
with the template bits removed for
brevity:
struct DoesNotCopyNorMove
{
DoesNotCopyNorMove() = default;
#ifdef __cpp_guaranteed_copy_elision
DoesNotCopyNorMove(const DoesNotCopyNorMove&) = delete;
DoesNotCopyNorMove(DoesNotCopyNorMove&&) = delete;
#else
private:
DoesNotCopyNorMove(const DoesNotCopyNorMove&);
DoesNotCopyNorMove(DoesNotCopyNorMove&&);
friend DoesNotCopyNorMove factory();
#endif
};
Again, for pre-C++17, using it looks like this:
auto&& x = factory(); // but NOT auto x = factory();
With C++17, the same syntax can be used, but by-value use is also possible:
auto x = factory();
Thoughts?
mandatory copy elision. This came up
in Qt: https://codereview.qt-project.org/#/c/206467/
So, we want to have a RAII handle that should not easily traverse
scopes. Since the RAII handle
wishes to store an arbitrary functor, we need to make it a template.
In order to avoid having to
force users to specify complex template arguments, we want to add a
factory function (we could
use Class Template Argument Deduction but that's another thing with
another macro). For C++17,
the factory can just return a noncopyable nonmovable type. For earlier
versions, we can befriend
the factory and require that users use lifetime-extending references
for the factory's return value.
With the envisioned macro, the class would look roughly like this,
with the template bits removed for
brevity:
struct DoesNotCopyNorMove
{
DoesNotCopyNorMove() = default;
#ifdef __cpp_guaranteed_copy_elision
DoesNotCopyNorMove(const DoesNotCopyNorMove&) = delete;
DoesNotCopyNorMove(DoesNotCopyNorMove&&) = delete;
#else
private:
DoesNotCopyNorMove(const DoesNotCopyNorMove&);
DoesNotCopyNorMove(DoesNotCopyNorMove&&);
friend DoesNotCopyNorMove factory();
#endif
};
Again, for pre-C++17, using it looks like this:
auto&& x = factory(); // but NOT auto x = factory();
With C++17, the same syntax can be used, but by-value use is also possible:
auto x = factory();
Thoughts?
Received on 2017-10-05 12:31:21