Re[6]: Variadic templates arguments position
От: _NN_ www.nemerleweb.com
Дата: 10.04.20 13:47
Оценка: 6 (1)
Здравствуйте, koenjihyakkei, Вы писали:

K>Здравствуйте, _NN_, Вы писали:


_NN>>В C++17 не будет ни копирования не перемещения, а будет отложенная материализация:


K>Ну вроде и так С++17, а ваш код с запрещенным копи конструктором не компилируется: https://gcc.godbolt.org/z/owCH7y


Можно перенести тело вспомогательных функций в сам класс и тогда всё собирается:

#include <type_traits>
#include <utility>
#include <tuple>


template<typename... Types>
decltype(auto) get_last_tuple_element(std::tuple<Types...> tp)
{
    return (std::get<std::tuple_size_v<std::tuple<Types...>> -1>(tp));
}



struct A
{
    A() {}
    A(int, int, int) {}
    A(A const&) = delete;
    A(A&&) = delete;
};


template<typename T>
struct B : public T
{
    template<typename... Args>
    B(Args&&... args) :
        B(std::forward_as_tuple(args...), std::make_index_sequence<sizeof...(Args) - 1>{}, get_last_tuple_element(std::tie(args...)) )
    {
    }

    int _v;

private:
    template<typename... Args, std::size_t... Is>
    B(std::tuple<Args...> tp, std::index_sequence<Is...>, int v) : T(std::get<Is>(tp)...), _v(v)
    {

    }
};

int main()
{
    B<A> b1(1);

    B<A> b(1, 2, 3, 4);
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[7]: Variadic templates arguments position
От: koenjihyakkei Россия  
Дата: 10.04.20 14:32
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>А почему перемещение запрещено ?


Много POD данных, которые по сути копируются, и есть данные, которые в принципе нельзя скопировать без приседаний.
Re[7]: Variadic templates arguments position
От: koenjihyakkei Россия  
Дата: 10.04.20 14:36
Оценка:
Здравствуйте, _NN_, Вы писали:

Это уже интереснее, мысль понятна, спасибо. Если обернуть еще макросами, то можно сократить количество вспомагательного кода, тогда менее верятно, что меня с этим пошлют А то эти struct B не только я буду писать.
Re[8]: Variadic templates arguments position
От: _NN_ www.nemerleweb.com
Дата: 10.04.20 14:50
Оценка:
Здравствуйте, koenjihyakkei, Вы писали:

K>Здравствуйте, _NN_, Вы писали:


K>Это уже интереснее, мысль понятна, спасибо. Если обернуть еще макросами, то можно сократить количество вспомагательного кода, тогда менее верятно, что меня с этим пошлют А то эти struct B не только я буду писать.


Полагаю можно поиграться с кодом и упростить, может с CRTP или другим подходом.
Всё же, если не критично ставить параметры класса вначале, а не в конце, то это будет лучшим решением.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Variadic templates arguments position
От: koenjihyakkei Россия  
Дата: 12.04.20 23:18
Оценка:
Здравствуйте, koenjihyakkei, Вы писали:

Если кому интересно, поигрался с версией от _NN_ и пришел к следующему варианту. Буду благодарен если кто подскажет, как можно улучшить.
Единственно у него есть один недостаток и возможно достаточно серьезный: не работает implicit conversion — компиляция падает с ошибкой "recursive template instantiation exceeded maximum depth", что в принципе логично.
То есть если конструктор ждет unsigned, а передается 123, а не 123u, то ошибка.
Причем если не менять параметр template-depth (по умолчанию он 1024) то компиляция может занимать приличное время. В общем неприятная ситуация получается.

http://coliru.stacked-crooked.com/a/facf23243c3cdbeb

#include <type_traits>
#include <utility>
#include <tuple>
#include <iostream>


#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)

#define MIXIN_INIT() T(std::get<Is>(tp)...)

#define MIXIN_CONSTRUCTOR(MIXIN, ...) \
    static constexpr size_t ArgsNum = VA_NARGS(__VA_ARGS__); \
    template<typename... Args>  \
    MIXIN(Args&&... args) : MIXIN(std::forward_as_tuple(args...), std::make_index_sequence<ArgsNum>{} ) {} \
    \
    template<typename... Args, std::size_t... Is> \
    MIXIN(std::tuple<Args...> tp, std::index_sequence<Is...>) : \
    MIXIN(tp, std::make_index_sequence<sizeof...(Args) - ArgsNum>{}, std::get<sizeof...(Args) - ArgsNum + Is>(tp)... ) {} \
    \
    template<typename... Args, std::size_t... Is> \
    MIXIN(std::tuple<Args...> tp, std::index_sequence<Is...>, __VA_ARGS__)


template<typename... Args>
void print(Args... args) {
    ((std::cout << ' ' << args), ...) << std::endl;
}

struct Base
{
    Base(int v1, const char* v2) : a(v1), b(v2) {}
    Base(Base const&) = delete;
    Base(Base&&) = delete;
    
    int a;
    const char* b;
};

template<typename T>
struct Foo : public T
{
    MIXIN_CONSTRUCTOR(Foo, bool v, float v2) : MIXIN_INIT(), c(v), d(v2) {}

    bool c;
    float d;
};


template<typename T>
struct Bar : public T
{
    MIXIN_CONSTRUCTOR(Bar, char c, float f, uint32_t n) : MIXIN_INIT(), ch(c), fl(f), num(n) {}

    char ch;
    float fl;
    uint32_t num;
};

struct Final : public Bar<Foo<Base>> {
    using Base = Bar<Foo<Base>>;
    using Base::Base;
};

int main()
{
    Foo<Base> f1(1, "hello", true, 1.0f);
    print(f1.a, f1.b, f1.c, f1.d);
    
    Bar<Base> f(1, "hello", 'a', 3.14f, 123u);
    print(f.a, f.b, f.ch, f.fl, f.num);
    
    Final f2(1, "hello", true, 1.24f, 'r', 3.14f, 123u);
    print(f2.a, f2.b, f2.c, f2.d, f2.ch, f2.fl, f2.num);
}
Re[2]: Variadic templates arguments position
От: _NN_ www.nemerleweb.com
Дата: 13.04.20 10:58
Оценка:
Здравствуйте, koenjihyakkei, Вы писали:

K>Здравствуйте, koenjihyakkei, Вы писали:


K>Если кому интересно, поигрался с версией от _NN_ и пришел к следующему варианту. Буду благодарен если кто подскажет, как можно улучшить.

K>Единственно у него есть один недостаток и возможно достаточно серьезный: не работает implicit conversion — компиляция падает с ошибкой "recursive template instantiation exceeded maximum depth", что в принципе логично.
K>То есть если конструктор ждет unsigned, а передается 123, а не 123u, то ошибка.
K>Причем если не менять параметр template-depth (по умолчанию он 1024) то компиляция может занимать приличное время. В общем неприятная ситуация получается.

Что-то сложно получилось.
Да ещё и макрос думаю упростить можно.

Кстати, нужно использовать Args&&... , чтобы избежать копирования


template<typename... Args>
void print(Args&&... args) {
    ((std::cout << ' ' << args), ...) << std::endl;
}


P.S.
https://www.walletfox.com/course/cheatsheets_cpp.php
http://rsdn.nemerleweb.com
http://nemerleweb.com
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.