我正在尝试编写一个模板函数,该函数将根据其模板参数执行一组 dynamic_casts()
。我有以下内容来说明:
class FooData
{
public:
virtual ~FooData() {};
};
class DerivedFooData: public FooData{};
class Other: public FooData{};
void bar(DerivedFooData* d1, DerivedFooData* d2) {}
void bar(DerivedFooData* d1, Other*, DerivedFooData* d2, Other*, Other*) {}
int main()
{
DerivedFooData d1,d2;
std::vector<FooData*> container1{&d1, &d2};
std::vector<FooData*> container2{&d1, &d2};
// I want bar to be called with container1[0] cast to DerivedFooData and container2[1] cast to DerivedFooData
// the first two template params are each container size
foo<1, 1, DerivedFooData, DerivedFooData>(container, container2);
// I want bar to be called with
// container1[0] cast to DerivedFooData
// container1[1] cast to Other
// container2[0] cast to DerivedFooData
// container2[1] cast to Other
// container2[2] cast to Other
foo<2, 3, DerivedFooData, Other, DerivedFooData, Other, Other>(container, container2);
}
我可以手动创建其中一些:
template <int N, int M, typename U, typename V>
void foo(const std::vector<FooData*>& input, const std::vector<FooData*>& output)
{
bar(dynamic_cast<U*>(input[0]), dynamic_cast<V*>(output[0]));
}
template <int N, int M, typename U, typename V, typename W, typename X, typename Y>
void foo(const std::vector<FooData*>& input, const std::vector<FooData*>& output)
{
bar(dynamic_cast<U*>(input[0]), dynamic_cast<V*>(input[1]), dynamic_cast<W*>(output[0]), dynamic_cast<X*>(output[1]), dynamic_cast<Y*>(output[2]));
}
但我不知道如何以通用方式指定 N
和 M
的所有组合。我假设可变参数模板会出现在某个地方,但我需要一些指导。
最佳答案
一点也不优雅(并且不确定确切的索引)但是......下面的东西(假设你可以使用 C++14)应该可以工作(如果我理解正确的话你想要什么)
template <std::size_t Dim1, typename ... Ts, std::size_t ... Is>
void foo_helper (std::index_sequence<Is...>, std::vector<FooData*> inV,
std::vector<FooData*> outV)
{ bar( dynamic_cast<Ts*>(Is < Dim1 ? inV[Is] : outV[Is-Dim1])... ); }
template <std::size_t Dim1, std::size_t Dim2, typename ... Ts>
void foo (std::vector<FooData*> inV, std::vector<FooData*> outV)
{ foo_helper<Dim1, Ts...>
(std::make_index_sequence<Dim1+Dim2>{}, inV, outV); }
我知道 C++20 对您来说太新了,但是为了好玩,我将向您展示如何使用新的 C++20 lambda 模板功能来避免使用辅助函数
// from C++20: foo_helper() isn't needed anymore
template <std::size_t Dim1, std::size_t Dim2, typename ... Ts>
void foo (std::vector<FooData*> inV, std::vector<FooData*> outV)
{ [&]<std::size_t ... Is>(std::index_sequence<Is...>)
{ bar( dynamic_cast<Ts*>(Is < Dim1 ? inV[Is] : outV[Is-Dim1])... ); }
(std::make_index_sequence<Dim1+Dim2>{}); }
下面是一个完整的编译C++14的例子
#include <vector>
#include <type_traits>
struct FooData { virtual ~FooData() {}; };
class DerivedFooData: public FooData { };
class Other : public FooData { };
void bar (DerivedFooData*, DerivedFooData*) {}
void bar (DerivedFooData*, Other*, DerivedFooData*, Other*, Other*) {}
template <std::size_t Dim1, typename ... Ts, std::size_t ... Is>
void foo_helper (std::index_sequence<Is...>, std::vector<FooData*> inV,
std::vector<FooData*> outV)
{ bar( dynamic_cast<Ts*>(Is < Dim1 ? inV[Is] : outV[Is-Dim1])... ); }
template <std::size_t Dim1, std::size_t Dim2, typename ... Ts>
void foo (std::vector<FooData*> inV, std::vector<FooData*> outV)
{ foo_helper<Dim1, Ts...>
(std::make_index_sequence<Dim1+Dim2>{}, inV, outV); }
int main ()
{
DerivedFooData d1, d2, d3;
std::vector<FooData*> container1 {&d1, &d2};
std::vector<FooData*> container2 {&d1, &d2, &d3};
foo<1, 1, DerivedFooData, DerivedFooData>(container1, container2);
foo<2, 3, DerivedFooData, Other, DerivedFooData, Other, Other>
(container1, container2);
}
关于c++ - 用于转换多个参数的模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57794926/