我目前正在清理一个充满函数模板的 API,并强烈希望编写以下代码。
template <typename T, typename U, typename V>
void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);
当我调用这个模板时,我想这样做如下。
std::string text("hello");
doWork(100, 20.0, &text);
doWork('a', text); // oops!
doWork<char, std::string, void>('a', text); // to verbose!
不幸的是,第二次调用无法编译,因为编译器无法推断出可选参数的类型。这是不幸的,因为我真的不在乎参数类型是什么,而是它的值是 NULL。另外,我想避免第三次调用的路线,因为它妨碍了可读性。
这导致我尝试使模板参数V
具有默认类型,这也不起作用,因为您不能将默认类型应用于函数模板参数(至少使用 VC++ 9.0)。
template <typename T, typename U, typename V = void> // oops!
void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);
我唯一剩下的选择是引入一个doWork
对模板参数一无所知的重载V
。
template <typename T, typename U>
void doWork(const T& arg1, const U& arg2)
{
doWork(arg1, arg2, 0);
}
template <typename T, typename U, typename V>
void doWork(const T& arg1, const U& arg2, V* optionalArg);
这是解决这个问题的最佳方法吗?我看到的唯一缺点是,如果函数模板包含许多具有合适默认值的参数,我可能会引入许多琐碎的转发函数。