LINUX.ORG.RU

c++, lambda, template, множественный аргумент и относительно старый gcc, можно ли переделать?!

 , ,


0

1

на удаленном ресурсе, обновили 1С, собственно я тоже под линукс 1С обновил, но там выползла новая зависимость на libwebkitgtk-3.0, раньше не было, вообщем почти все поборол.. заткнулся на этом

template <typename T, typename... Arguments>
class CrossThreadTaskImpl final : public CrossThreadTask {
public:
    CrossThreadTaskImpl(T* callee, void (T::*method)(Arguments...), Arguments&&... arguments)
    {
        m_taskFunction = [callee, method, arguments...] {
            (callee->*method)(arguments...);
        };
    }
};

gcc-4.8, ошибки такие

error: expected ‘,’ before ‘...’ token
         m_taskFunction = [callee, method, arguments...] {
                                                    ^
error: expected identifier before ‘...’ token
error: parameter packs not expanded with ‘...’:
         m_taskFunction = [callee, method, arguments...] {
                                                       ^
error: expansion pattern ‘arguments’ contains no argument packs
             (callee->*method)(arguments...);

как бы это переписать, лямбду распакую, туплю с множественным аргументом

★★★★★

Последнее исправление: anonymous2 (всего исправлений: 1)

что специалисты по с++ все пиво пьют, один я webkit компеляю.. пипец))

anonymous2 ★★★★★
() автор топика

Заменить один variadic template на 10 перегруженных функций: для 0 аргументов, для 1, для 2, и т.д.

vzzo ★★★
()

gcc-4.8

Может быть, лучше обновить gcc?

hateyoufeel ★★★★★
()
Ответ на: комментарий от anonymous2

Там аргументы могут быть разных типов. Тебе std::list не подойдёт.

hateyoufeel ★★★★★
()

Если gcc-4.8 не умеет захватывать argument pack в лямбде и нет возможности обновить компилятор, то можно сделать так:

* написать собственный аналог std::apply для того подмножества C++11, которое поддерживается в gcc-4.8;

* в конструкторе CrossThreadTaskImpl создавать экземпляр tuple и захватывать в лямбде этот самый вариант. Что-то вроде:

CrossThreadTaskImpl(T* callee, void (T::*method)(Arguments...), Arguments&&... arguments)
    {
        auto arg_tuple = std::make_tuple(std::forward<Arguments>(arguments)...);
        m_taskFunction = [callee, method, arg_tuple] {...};
    }

* внутри лябды делать вызов callee->method с помощью самодельного варианта std::apply.

Для C++11 я когда-то по материалам из Интернета сделал вот такую реализацию call_by_tuple, которая работала в gcc-4.8: https://wandbox.org/permlink/hGkf8piCihJQaL50

PS. Если тупл получается «тяжелым», то может быть накладно захватывать его в лямбде по значению (а сделать move при захвате в C++11 еще нельзя). И лучше тогда будет сперва создать тупл в динамической памяти, а лямбдой захватить shared_ptr на него. Что-то вроде:

auto arg_tuple = std::make_shared<std::tuple<Arguments...>>(
    std::forward<Arguments>(arguments)...);
m_taskFunction = [callee, method, arg_tuple] {...};

eao197 ★★★★★
()
-m_taskFunction = [callee, method, arguments...] {
+m_taskFunction = [=] {

? Но как-то это слишком просто.

xaizek ★★★★★
()
Ответ на: комментарий от anonymous2

поставить новый gcc был крайний вариант...

Фигня всё это. На вычислительных серверах как правило RHEL/CentOS 6/7, а компиляторов стоит десятки версий. И ничего. «Environment Modules» всё разрулит ;)

AlexVR ★★★★★
()
Ответ на: комментарий от anonymous2

А что его ставить? Собери тулчейн поновее и собирай им, обязательно чтоли системный использовать. У меня ваще все собирается тулчейном, который лежит в $HOME.

DELIRIUM ☆☆☆☆☆
()

Можно.

1. Берешь старый GCC.
2. Компилируешь им новый GCC.
3. Новым GCC собираешь libwebkit.
4. Профит!

rupert ★★★★★
()

а, случаем, не так должно было быть в исходнике?

CrossThreadTaskImpl(T* callee, void (T::*method)(Arguments...), Arguments&&... arguments)
    {
        m_taskFunction = [callee, method, arguments...] {
            (callee->*method)(std::forward<Arguments>(arguments)...);
        };
    }

xperious ★★
()

Классика штабильной шизни.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.