C ++将模板化函数传递给函数

C++ Passing templated functions to function

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

到目前为止,我还没有在 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++ 编译器设置的有用信息:

提前谢谢你:)

对于这种特殊情况,您可以通过使用 out_stream<std::stringstream>.

调用 doOperation 来帮助编译器推导出 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

正如评论中所建议的,除了传递函数模板的实例化之外,您还有其他选择:

  1. 更改 out_stream 以接受 std::ostream&
  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<std::stringstream>,成为函数。在调用 doOperation(out_stream); 中,编译器无法推断出实例化 out_stream 的类型。