sizeof(variadic pack...)
От: niXman Ниоткуда https://github.com/niXman
Дата: 26.10.17 14:17
Оценка:
привет!

есть функция, аргументы которой могут быть только фундаментальными типами.
хочу подсчитать суммарный размер всех аргументов этой функции.

зарукоблудил такое:

#include <iostream>
#include <tuple>

template<typename... Args>
constexpr std::uint8_t sizeofargs(const Args&...) {
#pragma pack(push, 1)
    struct tt { std::tuple<typename std::decay<Args>::type...> t; };
#pragma pack(pop)

    return sizeof...(Args) ? sizeof(tt) : 0;
}

int main(int argc, char **argv)
{
    std::cout << (int)sizeofargs() << std::endl;
    std::cout << (int)sizeofargs(argc) << std::endl;
    std::cout << (int)sizeofargs(argc, argv) << std::endl;
}

но как результат получаю такое:
0
4
16

где первые два верны, а последний — нет. похоже, что из-за выравнивания на 8. и #pragma pack(push, 1), в данном случае, почему-то, не помогает...

как победить? можно использовать С++11. (про fold expression знаю...)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: sizeof(variadic pack...)
От: watchmaker  
Дата: 26.10.17 14:32
Оценка: 15 (2) +4
Здравствуйте, niXman, Вы писали:

X>как победить? можно использовать С++11. (про fold expression знаю...)


Так обычный же шаблон использовать, не?

constexpr size_t sizeofargs() {
    return 0;
}


template<typename Head, typename... Args>
constexpr size_t sizeofargs(const Head& h, const Args&... tail) {
    return sizeof(h) + sizeofargs(tail...);
}
Re[2]: sizeof(variadic pack...)
От: niXman Ниоткуда https://github.com/niXman
Дата: 26.10.17 14:34
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Так обычный же шаблон использовать, не?

оф

спасибо, ушел отдыхать...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: sizeof(variadic pack...)
От: _NN_ www.nemerleweb.com
Дата: 30.10.17 20:10
Оценка:
Здравствуйте, niXman, Вы писали:

X>спасибо, ушел отдыхать...


Главное, чтобы не ушёл отдыхать на что-нибудь вроде Go
http://rsdn.nemerleweb.com
http://nemerleweb.com
Некорректное поведение Intel Compiler C++
От: Constructor  
Дата: 23.11.17 22:01
Оценка: +1
Здравствуйте, niXman, Вы писали:

X>есть функция, аргументы которой могут быть только фундаментальными типами.

X>хочу подсчитать суммарный размер всех аргументов этой функции.

X>...


X>как победить? можно использовать С++11. (про fold expression знаю...)


Fold expression из C++17 легко сэмулировать на C++11/C++14. Однако в C++11 constexpr-функции могут быть только однострочниками, поэтому следующий код компилируется исключительно в C++14 (и выше):

template <typename... Args>
constexpr std::uint8_t size_of_args(const Args&...)
{
    using Do = int[];
    std::uint8_t size{};
    
    (void)Do{0, (size += sizeof(Args), 0)...};
    
    return size;
}


Другой вариант решения на чистом C++11 (отличный от представленного
Автор: watchmaker
Дата: 26.10.17
watchmaker) может использовать рекурсию шаблонов класса:

template <typename...>
struct size_of;

template <>
struct size_of<>
{
    static constexpr std::uint8_t value{};
};

template <typename Head, typename... Tail>
struct size_of<Head, Tail...>
{
    static constexpr std::uint8_t value = sizeof(Head) + size_of<Tail...>::value;
};


template <typename... Args>
constexpr std::uint8_t size_of_args(const Args&...)
{
    return size_of<Args...>::value;
}
Отредактировано 23.11.2017 22:04 Constructor . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.