【问题标题】:Can I use a function object without instantiation?我可以使用没有实例化的函数对象吗?
【发布时间】:2026-01-17 10:05:02
【问题描述】:

有以下代码:

template<typename T, typename OutStream = std::ostream> struct print {
  OutStream &operator()(T const &toPrint, OutStream &outStream = std::cout) const {
    outStream << toPrint;
    return outStream;
  }
};

这个调用是错误的:

print<int>(2);

错误信息:

1>main.cpp(38): error C2440: '<function-style-cast>' : cannot convert from 'int' to 'print<T>'
1>          with
1>          [
1>              T=int
1>          ]
1>          No constructor could take the source type, or constructor overload resolution was ambiguous

这个调用没有错误:

print<int> intPrinter;
intPrinter(2);

我可以在没有实例化的情况下以某种方式使用函数对象吗? 我不能在这里使用模板函数,因为我需要部分特化能力。

【问题讨论】:

    标签: c++ templates constructor function-object


    【解决方案1】:

    我觉得你想说

    print<int>()(2);
    

    在这里,第一个括号通过调用(零参数)构造函数创建一个临时的print&lt;int&gt; 对象,然后第二个括号实际调用该对象上的函数调用运算符。您现在遇到的错误是由于

    print<int>(2);
    

    被解释为将 2 转换为 print&lt;int&gt; 的类型转换表达式,这不是您想要的(也不合法)。

    希望这会有所帮助!

    【讨论】:

      【解决方案2】:

      对于那些无状态的包装类,使用静态成员函数可能会更好:

      template<typename T, typename OutStream = std::ostream>
      struct printer
      {
          static OutStream & print()(T const &toPrint, OutStream &outStream = std::cout)
          {
              outStream << toPrint;
              return outStream;
          }
      };
      

      然后您可以使用printer&lt;Foo&gt;::print(x); 调用它们,并且您通常可以提供一个类型推断的辅助函数模板:

      template <typename T> std::ostream & print(T const & x)
      {
          return printer<T, std::ostream>::print(x);
      }
      

      现在你可以直接说print(x);

      【讨论】:

      • +1 谢谢。这很棒。您的回答非常有帮助,现在我无法选择答案...
      • @DaddyM:选择你认为对你最有帮助的东西。不用担心:-)
      • 这是为模板提供一组不需要状态(例如您在仿函数对象中具有)的功能集的标准习惯用法,按类型专门化。标准库中的 char_traits 类是一个很好的具体示例 - 它们为字符串和流的不同字符类型提供所有具体行为。
      最近更新 更多