【问题标题】:Callback function in a templated function accepting variable argument type using `switch` statement使用`switch`语句接受可变参数类型的模板函数中的回调函数
【发布时间】:2021-10-18 10:26:32
【问题描述】:

我正在尝试从模板函数中调用回调函数。但是回调函数的参数取决于switch 语句。

这是解释我打算使用玩具示例做什么的工作代码。

#include <vector>

struct A {};
struct B {};
struct C {};
struct D {};

enum class StructType
{
  A,
  B,
  C,
  D
};

std::vector<A> vec_A;
std::vector<B> vec_B;
std::vector<C> vec_C;
std::vector<D> vec_D;


template <template <class> class Container, class ValueType>
void process(const StructType& struct_type)
{
  auto callback = [&](Container<ValueType>& v) {};

  switch(struct_type)
  {
    case StructType::A:
      callback(vec_A);
      break;
    case StructType::B:
      callback(vec_B);
      break;
    case StructType::C:
      callback(vec_C);
      break;
    case StructType::D:
      callback(vec_D);
      break;
  }
}


int main()
{
  process<std::vector, A>(StructType::A);

}

在编译时,我收到以下错误:

$ g++ template.cpp 
template.cpp: In instantiation of ‘void process(const StructType&) [with Iterator = std::vector; ValueType = A]’:
template.cpp:47:26:   required from here
template.cpp:33:15: error: no match for call to ‘(process<std::vector, A>(const StructType&)::<lambda(std::vector<A>&)>) (std::vector<B>&)’
   33 |       callback(vec_B);
      |       ~~~~~~~~^~~~~~~
template.cpp:25:19: note: candidate: ‘process<std::vector, A>(const StructType&)::<lambda(std::vector<A>&)>’
   25 |   auto callback = [&](Iterator<ValueType>& v) {};
      |                   ^
template.cpp:25:19: note:   no known conversion for argument 1 from ‘std::vector<B>’ to ‘std::vector<A>&’
template.cpp:36:15: error: no match for call to ‘(process<std::vector, A>(const StructType&)::<lambda(std::vector<A>&)>) (std::vector<C>&)’
   36 |       callback(vec_C);
      |       ~~~~~~~~^~~~~~~
template.cpp:25:19: note: candidate: ‘process<std::vector, A>(const StructType&)::<lambda(std::vector<A>&)>’
   25 |   auto callback = [&](Iterator<ValueType>& v) {};
      |                   ^
template.cpp:25:19: note:   no known conversion for argument 1 from ‘std::vector<C>’ to ‘std::vector<A>&’
template.cpp:39:15: error: no match for call to ‘(process<std::vector, A>(const StructType&)::<lambda(std::vector<A>&)>) (std::vector<D>&)’
   39 |       callback(vec_D);
      |       ~~~~~~~~^~~~~~~
template.cpp:25:19: note: candidate: ‘process<std::vector, A>(const StructType&)::<lambda(std::vector<A>&)>’
   25 |   auto callback = [&](Iterator<ValueType>& v) {};
      |                   ^
template.cpp:25:19: note:   no known conversion for argument 1 from ‘std::vector<D>’ to ‘std::vector<A>&’

我的g++ 版本是:11.1.0

我可以理解错误,但不知道如何解决。

非常感谢任何帮助。谢谢。

编辑 1:Iterator -> Container @Ted Lyngmo 建议的模板类型更有意义。

【问题讨论】:

  • 您有一个仅在运行时才知道的函数参数,但它取决于模板参数中的编译时类型。在这种情况下你真的需要运行时参数吗? Example 无关:Iterator 是模板参数的一个奇怪名称。 Container 可能更合适。
  • 那么,你是不是建议我只使用auto callback = [&amp;](const auto&amp; v) {};?因为这不能使用-std=c++14 标志编译。
  • 我在质疑为什么您必须将StructType::A 提供给process。如果你用process&lt;std::vector, A&gt;(StructType::B); 调用它会发生什么?
  • 这只是一个玩具示例。在实际实现中,process 被不同类型的Struct 调用,我只是想在这里以Struct::A 为例来模拟这种行为。或者更确切地说,进程是通过一个容器传递的,该容器具有调用callback的不同类型的矢量数据。
  • 所以,从参数到函数,StructType::A 你知道它应该使用std::vector&lt;A&gt; - 但该信息已经在模板参数中(就像我在顶部的示例中显示的那样)。我仍然看不到通过运行时参数提供相同信息的原因。

标签: c++ templates vector c++14


【解决方案1】:

正如您的错误所说,您尚未创建的 callback 函子没有匹配项。

我建议删除 process 的运行时参数并仅使用函数模板参数中的信息。

例子:

#include <vector>
#include <type_traits>

struct A {};
struct B {};
struct C {};
struct D {};

// enum class StructType {A, B, C, D }; // perhaps not needed anymore

std::vector<A> vec_A;
std::vector<B> vec_B;
std::vector<C> vec_C;
std::vector<D> vec_D;

template<class T> auto& get_vec();
template<> auto& get_vec<std::vector<A>>() { return vec_A; }
template<> auto& get_vec<std::vector<B>>() { return vec_B; }
template<> auto& get_vec<std::vector<C>>() { return vec_C; }
template<> auto& get_vec<std::vector<D>>() { return vec_D; }

template <template <class, class...> class Container, class ValueType>
void process() {
    using container_type = Container<ValueType>;

    auto callback = [&](container_type&) {};
    callback(get_vec<container_type>());
}

int main() {
    process<std::vector, A>();
}

【讨论】:

    猜你喜欢
    • 2021-10-01
    • 2021-03-29
    • 2018-02-26
    • 2022-10-18
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多