【发布时间】:2013-02-02 10:11:29
【问题描述】:
我有以下标签调度代码(见LiveWorkSpace)
#include <iostream>
// traits types
struct A {}; struct B {}; struct C {};
// helpers
void fun_impl(bool, A) { std::cout << "A\n"; }
void fun_impl(bool, B) { std::cout << "B\n"; }
// would like to eliminate this
void fun_impl(bool b, C)
{
if(b)
fun_impl(b, A());
else
fun_impl(b, B());
}
template<typename T>
void fun(bool b, T t)
{
// T = A, B, or C
fun_impl(b, t);
}
int main()
{
fun(true, A()); // "A"
fun(false, A()); // "A"
fun(true, B()); // "B"
fun(false, B()); // "B"
fun(true, C()); // "A"
fun(false, C()); // "B"
}
但是,这个标签调度与函数fun 密切相关,我需要维护 3 个辅助函数来为每个使用它的函数实现这个标签调度。
参数推导失败:我尝试将fun_impl抽象为mixed_dispatch函数对象的模板参数,但如果我随后将fun_impl作为参数传递,则不能推断出应该需要 2 个重载中的哪一个。
template<typename T>
struct mixed_dispatch
{
template<typename Fun>
void operator()(Fun f, bool b)
{
return f(b, T());
}
};
template<>
struct mixed_dispatch<C>
{
template<typename Fun>
void operator()(Fun f, bool b)
{
if (b)
return f(b, A());
else
return f(b, B());
}
};
template<typename T>
void fun(bool b, T)
{
// T = A, B, or C
mixed_dispatch<T>()(fun_impl, b); // ERROR: Fun cannot be deduced
}
问题:有没有其他方法可以将标签调度与被调用的函数解耦?
我愿意接受任何使用 C++11 可变参数模板/Boost.Fusion 或其他简化我当前代码的魔法的建议(我现在必须为使用此特定调度的每个函数维护 3 个而不是 2 个辅助函数,并且随着更复杂的调度,辅助函数的数量增长得更快)。
【问题讨论】:
-
不能根据参数的值指定返回类型。
-
@ipc 我意识到这不能在编译时完全完成,但也许一些协变返回类型的诡计或联合可以在这里提供帮助?
-
b的值在编译时是否已知? -
@jrok 不,它是一个运行时变量
-
我不确定哪种代码对您来说更简单。我假设你有更多像 (A,B,C) 这样的三元组,对吧?您想如何告知每个 C 应该选择哪个 A 或 B?
标签: c++ templates c++11 variadic-templates boost-fusion