Информация об изменениях

Сообщение Re[3]: хочуфичу - функции-конструкторы от 29.12.2023 12:34

Изменено 29.12.2023 12:45 rg45

Re[3]: хочуфичу - функции-конструкторы
Здравствуйте, Кодт, Вы писали:

К>
К>template<class T, class... A>
К>concept Constructible = requires(A... a) { T(a...); };
К>


Немного оффтопа: в таком виде этот концепт не будет работать для классов, конструируемых по rvalue ссылкам — по той причине, что a... в теле концепта являются lvalue выражениями. И не просто не будет работать, а его использование будет невозможным ни под каким соусом:

http://coliru.stacked-crooked.com/a/8c51faa24ba97d64

#include <memory>

template<class T, class... A>
concept Constructible = requires(A... a) { T(a...); };

struct Foo
{
   Foo(std::unique_ptr<int>&&) {}
};

int main()
{
    static_assert( ! Constructible<Foo, std::unique_ptr<int>>);   // NOT constructible
    static_assert( ! Constructible<Foo, std::unique_ptr<int>&&>); // NOT constructible
}


Если не хочется тащить в концепт perfect forwarding ссылки, то этого можно не делать, но использовать std::forward очень желательно:

template<class T, class... A>
concept Constructible = requires(A... a) { T(std::forward<A>(a...)); };
Re[3]: хочуфичу - функции-конструкторы
Здравствуйте, Кодт, Вы писали:

К>
К>template<class T, class... A>
К>concept Constructible = requires(A... a) { T(a...); };
К>


Немного оффтопа: в таком виде этот концепт не будет работать для классов, конструируемых по rvalue ссылкам — по той причине, что a... в теле концепта являются lvalue выражениями. И не просто не будет работать, а его использование будет невозможным ни под каким соусом:

http://coliru.stacked-crooked.com/a/8c51faa24ba97d64

#include <memory>

template<class T, class... A>
concept Constructible = requires(A... a) { T(a...); };

struct Foo
{
   Foo(std::unique_ptr<int>&&) {}
};

int main()
{
    static_assert( ! Constructible<Foo, std::unique_ptr<int>>);   // NOT constructible
    static_assert( ! Constructible<Foo, std::unique_ptr<int>&&>); // NOT constructible
}


Если не хочется тащить в концепт perfect forwarding ссылки, то этого можно не делать (это вопрос семантики, которую мы хотим заложить в концепт), но использовать std::forward очень желательно в любом случае:

template<class T, class... A>
concept Constructible = requires(A... a) { T(std::forward<A>(a...)); };