Нет типа с именем «аргумент_тип» - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть эта функция:

void CGuild::AddComment(LPCHARACTER ch, const std::string& str)
{   if (str.length() > GUILD_COMMENT_MAX_LEN)
        return;

    char text[GUILD_COMMENT_MAX_LEN * 2 + 1];
    DBManager::instance().EscapeString(text, sizeof(text), str.c_str(), str.length());

    DBManager::instance().FuncAfterQuery(void_bind([this](auto&& data) { return this->RefreshCommentForce(data); }, ch->GetPlayerID()),
            "INSERT INTO guild_comment%s(guild_id, name, notice, content, time) VALUES(%u, '%s', %d, '%s', NOW())", 
            get_table_postfix(), m_data.guild_id, ch->GetName(), (str[0] == '!') ? 1 : 0, text);
}

, и я компилирую с помощью clang ++ - разработка на C ++ 1z, в среде Linux.Файл генерирует эту ошибку:

./any_function.h:41:15: error: no type named 'argument_type' in '(lambda at
      guild.cpp:1023:49)'
                typename F::argument_type value;
                ~~~~~~~~~~~~^~~~~~~~~~~~~
guild.cpp:1023:39: note: in instantiation of template class 'void_binder<(lambda
      at guild.cpp:1023:49)>' requested here
        DBManager::instance().FuncAfterQuery(void_bind([this](auto&& dat...
                                             ^

, а вот any_function.h:

template <class F>
class void_binder
{
    protected:
        F f;
        typename F::argument_type value;
    public:
        void_binder(const F& f, const typename F::argument_type x)
            : f(f), value(x) {}
        void operator()() const {
            return f(value);
        }
};

template <class F, class Arg> 
inline void_binder<F> void_bind(const F& f, const Arg& arg)
{
    typedef typename F::argument_type arg_type;
    return void_binder<F>(f, arg_type(arg));
}

Как я могу устранить эту ошибку?

Спасибо за ваши комментарии.

1 Ответ

0 голосов
/ 13 декабря 2018

Если я правильно понимаю, вы используете в void_bind() тип, полученный из первого аргумента шаблона, F,

F::argument_type

, который является typename (устарело, в C ++ 17) определено в std::function<R(Args...)>, но только когда Args... имеет только один тип (только когда функция получает только один аргумент).

Но вы передаете void_bind() универсальную лямбду

FuncAfterQuery(void_bind([this](auto&& data) { return this->RefreshCommentForce(data); }, [...]

, который не является std::function и не определяет argument_type

Поэтому я предлагаю (но я не могу доказать ... ваш пример неоптимален) сохранить лямбду всоответствующий std::function и передать std::function в void_bind()

что-то типа

std::function<RetType(ArgType)>
   f { [this](auto&& data) { return this->RefreshCommentForce(data); } };

FuncAfterQuery(void_bind(f, ch->GetPlayerID()), [...]

с соответствующими (?) RetType и ArgType типами.

...