Ste*_*idi 1 c++ templates optional-parameters optional-arguments function-templates
我正在努力清理一个充满功能模板的API,并且强烈希望编写以下代码.
template <typename T, typename U, typename V>
void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);
Run Code Online (Sandbox Code Playgroud)
当我调用此模板时,我想按照以下方式执行此操作.
std::string text("hello");
doWork(100, 20.0, &text);
doWork('a', text); // oops!
doWork<char, std::string, void>('a', text); // to verbose!
Run Code Online (Sandbox Code Playgroud)
不幸的是,第二次调用没有编译,因为编译器无法推断出可选参数的类型.这很不幸,因为我真的不在乎参数类型是什么,而是它的值是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);
Run Code Online (Sandbox Code Playgroud)
我唯一剩下的选择是引入一个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);
Run Code Online (Sandbox Code Playgroud)
这是解决这个问题的最佳方法吗?我看到的唯一缺点是,如果函数模板包含许多具有合适默认值的参数,我可能会引入许多简单的转发函数.
我认为您的转发功能是一个非常合适的解决方案,虽然在您的解决方案中,您不必明确指定模板参数吗?(0是一个整数常量,可以转换为任何V*类型.)另外doWordvs doWork?
作为一般规则,尽量避免可选参数,因为它们没有非常强大的回报.
它可能你函数来只需添加一个更容易强制客户端, (void*)0如果appriopriate不是增加多少额外的机制,同时支持两个参数和模板的三个参数的版本.但这取决于预期的用途.