当前位置: 首页 > 知识库问答 >
问题:

为什么我不能用可选的UnaryPredicate参数创建模板函数?

仲孙善
2023-03-14

我试图创建一个带有可选参数的模板函数,但我很难理解编译失败的原因。这是我的测试(设计)代码:

#include <iostream>
#include <vector>

template <class UnaryPredicate>
int GetCountIf(std::vector<int> v, UnaryPredicate pred = [](auto) { return true; }) {
  int count=0;
  for (auto i: v) {
    if (pred(i)) {
      count++;
    }
  }
  return count;
}

int main() {
  auto v = std::vector<int>{0, 1, 2, 3, 4, 5};
  std::cout << "NumOddElements=" << GetCountIf(v, [](auto val) { return (val % 2 == 1); }) << '\n';
  // std::cout << "NumElements=" << GetCountIf(v) << '\n';
}

只有当我用这两个参数调用getcountif()时,代码才会编译。如果我尝试只传递1个参数,编译将失败,出现以下错误:

main.cpp:18:34:错误:调用'GetCountIf'
std::cout<<“numelements=”<

template <typename T, class UnaryPredicate = std::function<bool(T)>>
int GetCountIf(std::vector<T> v, UnaryPredicate pred = [](T) { return true;}) {
  ...
}

(我用的是C++14)

共有1个答案

秦凯旋
2023-03-14

注意,函数参数的默认值不会用于模板参数的模板参数推导;导致模板参数推导失败,则无法推导UnaryPredicate的类型。

参见非推导上下文。

在以下情况下,用于组成P的类型、模板和非类型值不参与模板参数推导,而是使用在其他地方推导或显式指定的模板参数。如果模板参数仅在非推导上下文中使用且未显式指定,则模板参数推导将失败。

template<typename T, typename F>
void f(const std::vector<T>& v, const F& comp = std::less<T>());
std::vector<std::string> v(3);
f(v); // P1 = const std::vector<T>&, A1 = std::vector<std::string> lvalue
      // P1/A1 deduced T = std::string
      // P2 = const F&, A2 = std::less<std::string> rvalue
      // P2 is non-deduced context for F (template parameter) used in the
      // parameter type (const F&) of the function parameter comp,
      // that has a default argument that is being used in the call f(v)
template<typename T> void f(T = 5, T = 7);

void g()
{
    f(1);     // OK: calls f<int>(1, 7)
    f();      // error: cannot deduce T
    f<int>(); // OK: calls f<int>(5, 7)
}
 类似资料:
  • 考虑以下示例: 我的GCC 9.2.0无法编译并出现以下错误: 但是,工作正常。为什么会这样?如何使用显式模板参数调用foo?

  • 我正在学习一个视频教程,我想声明一个模板函数作为模板类的朋友。我不知道为什么代码会抛出错误。 编译器抛出错误。 错误: templates\u friends\u 38。cpp:在“void doSomething2(T)[T=int]”的实例化中:templates\u friends\u 38。cpp:40:19:此处需要templates\u friends\u 38。cpp:32:9:错误

  • 我的代码中只有参数化构造函数,需要通过它进行注入。 我想刺探参数化构造函数以注入模拟对象作为junit的依赖项。 但我们有什么东西可以在构造函数中注入模拟对象并对其进行监视吗?。

  • 以下内容将无法编译: null 我不明白这里到底出了什么问题。为什么编译器不能从函数参数推导出模板参数? 我需要做什么才能让这个工作?

  • 我希望维护语法,但似乎只能将typenames放在括号中,而不能将类放在括号中。以下是我当前的代码: 问题1:我找不到一种方法来使“default”参数对于特殊化不是必需的。我尝试了使用默认构造函数的代理类,将第三个参数更改为指针,并指定nullptr(这在语法上并不理想)和对类型的常量引用(这仍然需要用户端的三个参数),但似乎没有任何东西允许在中接受两个参数。 问题2:我找不到正确的语法来获得混

  • 我有以下代码: 这段代码会导致编译错误。使用< code>g -std=c 1z编译时,错误显示如下: 使用< code>clang -std=c 1z时,错误为: 我在MSYS2 MinGW-w64环境中运行这些。我的GCC版本是GCC 7.1.0,我的Clang版本是4.0.0;我在GCC和Clang中使用的标准库是与我的GCC编译器捆绑在一起的libstdc。 在我看来,对函数templat