我有一个模板函数,其中唯一的模板参数用于传递函数指针,我希望能够设置一个默认参数(一个特定的函数)加载到那个参数,但是它似乎并不像我预期的那样工作。为模板参数设置一个默认参数不允许我调用省略默认参数的函数,除非我创建一个单独的重载。有没有一种方法可以使用默认参数来实现这一点?
下面是我最初尝试的方法,validator
是一个有问题的参数:
template <typename FuncT>
std::string ask_for(size_t arg_index, const std::string & prompt,
FuncT validator = Validators::is_not_empty, // default does not work!
std::ostream & os = std::cout);
(Validators
是包含要传递给此函数的帮助器函数的命名空间。)
最后一个参数os
对默认参数的React与我预期的一样; ask_for(0, Validators::does_file_exist)
可以在os
设置为std::cout
的情况下工作。
但是如果我调用ask_for(1)
,它不会像我期望的那样调用ask_for(1, Validators::is_not_empty)
,而是给我这个错误跟踪:
error: no matching function for call to 'ask_for(int, const char [64])'
note: candidate: 'template<class FuncT> std::string ask_for(size_t, const std::string&, FuncT, std::ostream&)'
note: template argument deduction/substitution failed:
note: couldn't deduce template parameter 'FuncT'
它不应该能够通过给定的默认参数推导出模板参数吗?或者我误解了模板参数的默认参数是如何实现的?
但是,我能够通过编写一个单独的重载并调用它来获得预期的行为:
template <typename FuncT>
std::string ask_for(size_t arg_index, const std::string & prompt,
FuncT validator, // no default here...
std::ostream & os = std::cout);
// ...overloaded version calls function with desired default argument
std::string ask_for(size_t arg_index, const std::string & prompt)
{
return ask_for(arg_index, prompt, Validators::is_not_empty);
}
有没有办法将模板化参数的默认实参设置为函数指针,或者我必须创建一个单独的重载来实现这一点?使用模板专用化是否可行,或者如果我完全删除模板参数并使用一个特定的函数指针来代替?
为了可读性,我希望使用默认的参数符号,但我最感兴趣的是效率。
1条答案
按热度按时间gmol16391#
默认参数不能用于推导模板参数,但也可以使用默认值
FuncT
。