【问题标题】:C++ Passing templated functions to functionC ++将模板函数传递给函数
【发布时间】:2022-01-27 03:47:01
【问题描述】:

我需要将模板函数传递给函数。

到目前为止,我还没有在 google 上找到任何好的建议。 这是我尝试过的:

#include <iostream>
#include <sstream>
using namespace std;

struct event {
  bool signal;
};

template<typename T>
void out_stream(T &stream, event &evt) {
  stream << evt.signal;
}

template <typename F>
void doOperation(F f)
{
  event test;
  test.signal = 0;
  stringstream ss;

  f(ss, test);
}

int main() {

  doOperation(out_stream);

  return 0;
}

这就是编译器给我的错误:

main.cc:27:3: error: no matching function for call to 'doOperation'
  doOperation(out_stream);
  ^~~~~~~~~~~
main.cc:16:6: note: candidate template ignored: couldn't infer template argument 'F'
void doOperation(F f)
     ^
1 error generated.

一些(我希望)关于我的 g++ 编译器设置的有用信息:

  • Apple clang 版本 13.0.0 (clang-1300.0.29.30)
  • 目标:x86_64-apple-darwin20.6.0
  • 线程模型:posix

提前谢谢你:)

【问题讨论】:

  • 在您的情况下,将 T 更改为 ostream 并删除模板。通常,将函数包装在通用 lambda 中。
  • 不接受模板,您可以接受类型为 template&lt;typename T&gt; using F = void (*)(T&amp;, event&amp;); 的函数指针,专门用于 stringstream

标签: c++ function templates compiler-errors


【解决方案1】:

对于这种特殊情况,您可以通过调用doOperationout_stream&lt;std::stringstream&gt; 来帮助编译器推断T

另外,在doOperation 中,您需要使用f 而不是F

[Demo]

#include <iomanip>  // boolalpha
#include <iostream>  // cout
#include <sstream>  // stringstream

struct event {
    bool signal{};
};

template<typename T>
void out_stream(T& stream, const event& evt) {
    stream << std::boolalpha << evt.signal;
}

template <typename F>
void doOperation(F&& f) {
    std::stringstream ss{};
    f(ss, event{true});
    std::cout << ss.str() << "\n";
}

int main() {
    doOperation(out_stream<std::stringstream>);
}

// Outputs:
//
//   true

不过,正如 cmets 中所建议的,除了传递函数模板的实例之外,您还有其他选项:

  1. out_stream 更改为接受std::ostream&amp;
  2. 传递一个只调用函数模板实例化的通用 lambda。

[Demo]

#include <iomanip>  // boolalpha
#include <iostream>  // cout
#include <sstream>  // stringstream

struct event {
    bool signal{};
};

void out_stream1(std::ostream& stream, const event& evt) {
    stream << std::boolalpha << evt.signal;
}

template <typename T>
void out_stream2(T& stream, const event& evt) {
    stream << std::boolalpha << evt.signal;
}

template <typename F>
void doOperation(F&& f) {
    std::stringstream ss{};
    f(ss, event{true});
    std::cout << ss.str() << "\n";
}

int main() {
    doOperation(out_stream1);
    doOperation([](auto& stream, const auto& evt) { out_stream2(stream, evt); });
}

// Outputs:
//
//   true
//   true

请注意,没有模板函数,而是函数模板out_stream 是一个函数模板,需要用给定的类型实例化,例如out_stream&lt;std::stringstream&gt;,成为一个函数。在调用doOperation(out_stream); 中,编译器无法推断出实例化out_stream 的类型。

【讨论】:

    猜你喜欢
    • 2016-06-01
    • 2017-12-25
    • 2012-03-07
    • 2017-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多