使用“switch”语句接受可变参数类型的模板函数中的回调函数

Callback function in a templated function accepting variable argument type using `switch` statement

我正在尝试从模板函数中调用回调函数。但是回调函数的参数取决于 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 所建议的那样。

正如您的错误所述,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>();
}