使用“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>();
}
我正在尝试从模板函数中调用回调函数。但是回调函数的参数取决于 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>();
}