c++ 如何将模板化函数参数的默认实参设置为函数指针?

rjee0c15  于 2022-12-24  发布在  其他
关注(0)|答案(1)|浏览(149)

我有一个模板函数,其中唯一的模板参数用于传递函数指针,我希望能够设置一个默认参数(一个特定的函数)加载到那个参数,但是它似乎并不像我预期的那样工作。为模板参数设置一个默认参数不允许我调用省略默认参数的函数,除非我创建一个单独的重载。有没有一种方法可以使用默认参数来实现这一点?
下面是我最初尝试的方法,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);
}

有没有办法将模板化参数的默认实参设置为函数指针,或者我必须创建一个单独的重载来实现这一点?使用模板专用化是否可行,或者如果我完全删除模板参数并使用一个特定的函数指针来代替?
为了可读性,我希望使用默认的参数符号,但我最感兴趣的是效率。

gmol1639

gmol16391#

默认参数不能用于推导模板参数,但也可以使用默认值FuncT

template <typename FuncT = decltype(&Validators::is_not_empty)>
std::string ask_for(size_t arg_index,
                    const std::string & prompt,
                    FuncT validator = &Validators::is_not_empty,
                    std::ostream & os = std::cout);

相关问题