【问题标题】:C++ Build error: expected type-specifier before [Variadic templates] classC++ 构建错误:[可变参数模板] 类之前的预期类型说明符
【发布时间】:2021-11-19 09:52:03
【问题描述】:

这是我的代码:

#include <stdio.h>
#include <utility>
#include <tuple>

template <typename Obj, typename Method, typename Args, size_t... Ns>
inline void DispatchToMethodImpl(const Obj& obj, Method method, Args&& args,
                                 std::index_sequence<Ns...>) {
  (obj->*method)(std::get<Ns>(std::forward<Args>(args))...);
}

template <typename Obj, typename Method, typename Args>
inline void DispatchToMethod(const Obj& obj, Method method, Args&& args) {
  constexpr size_t size = std::tuple_size<std::decay_t<Args>>::value;
  DispatchToMethodImpl(obj, method, std::forward<Args>(args),
                       std::make_index_sequence<size>());
}

class TaskEventBase {
 public:
  virtual void Run() = 0;
};

template <typename Obj, typename Method, typename Args>
class TaskEvent : public TaskEventBase {
 public:
  TaskEvent(Obj* obj, Method method, Args&& args) {
    obj_ = obj;
    method_ = method;
    args_ = std::forward<Args>(args);
  }

  void Run() override { DispatchToMethod(obj_, method_, args_); }

 private:
  Obj* obj_;
  Method method_;
  Args args_;
};


int main() {
  printf("event loop test start\n");
  struct Foo {
    int x;
    int y;

    int Add(int a, int b) {
      printf("res is %d\n", a + b);
      return a + b;
    }
  };

  Foo foo;
  DispatchToMethod(&foo, &Foo::Add, std::make_tuple(1, 2));
  auto e = new TaskEvent(&foo, &Foo::Add, std::make_tuple(1, 2));
  printf("event loop test end\n");

  return 0;
}

尝试构建: g++ -g -Wall -std=c++14 -o test_template_args.cc

然后我得到以下错误:

test_template_args.cc:70:16: error: expected type-specifier before ‘TaskEvent’                                                                                   
   auto e = new TaskEvent(&foo, &Foo::Add, std::make_tuple(1, 2));      

我不明白 DispatchToMethod 函数模板为什么起作用:

DispatchToMethod(&foo, &Foo::Add, std::make_tuple(1, 2));

但是TaskEvent类模板不起作用:

auto e = new TaskEvent(&foo, &Foo::Add, std::make_tuple(1, 2));

【问题讨论】:

    标签: c++14 variadic-templates stdtuple index-sequence


    【解决方案1】:

    由于CTAD,您的代码从 C++17 开始工作。

    直到C++14,代码不起作用,因为TaskEvent的构造函数是非模板函数,所以不能从TaskEvent构造函数的调用参数中推导出类模板参数,与DispatchToMethod相反,它是模板函数 - 所有ObjMethodArgs 都可以从函数调用的传递参数中推导出来。

    您可以通过模板参数列表显式提供模板参数:

      auto e = new TaskEvent< Foo,int(Foo::*)(int,int),std::tuple<int,int> >
                        (&foo, &Foo::Add, std::make_tuple(1, 2));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多