【问题标题】:Cast std::endl to a function pointer将 std::endl 转换为函数指针
【发布时间】:2014-10-10 15:39:24
【问题描述】:

这是How template function chooses parameter?的后续问题

@Kerrek SB提出以下解决方案:

Func(static_cast<std::ostream&(&)(std::ostream&)>(std::endl));

我还发现以下代码也适用于我:

Func(static_cast<std::ostream&(*)(std::ostream&)>(std::endl));

问题>首选哪种方法?

【问题讨论】:

  • 像数组、函数和对函数的引用一样,隐式衰减为指向函数的指针。函数调用运算符() 两者都可以使用。我倾向于明确地创建和使用函数指针(所以第二个会说&amp;std::endl),但这确实是风格问题。
  • 或者更简单的Func&lt;std::ostream&amp;(std::ostream&amp;)&gt;(std::endl)
  • @BenVoigt:严格来说,函数调用运算符()以函数指针为前缀工作。如果给它一个函数类型或函数引用类型的表达式,则该表达式将在() 运算符看到它之前隐式衰减到一个指针。使用函数类型的表达式作为() 的前缀不仅是非法的;不可能。 (除非我遗漏了一些时髦的 C++42 标准特性,这些特性使得它在一些奇怪的极端情况下成为可能。)
  • @Keith:不,当用作函数调用运算符的操作数时,函数不会衰减,并且使用函数类型的表达式是完全合法的。 5.2.2 以“函数调用是一个后缀表达式后跟括号,其中包含一个可能为空的逗号分隔的初始化子句列表,这些子句构成函数的参数。后缀表达式应具有函数类型或指向函数类型。”
  • @BenVoigt:嗯。我会检查标准并稍后回复。

标签: c++ stl


【解决方案1】:

我会这样做:

template<class Sig>
struct reference_to_function {};
template<class R, class... Args>
struct reference_to_function<R(Args...)> {
  using type = R(&)(Args...);
};
template<class Sig>
using sig_t = typename reference_to_function<Sig>::type;

template<class Sig>
sig_t<Sig> pick_signature( sig_t<Sig> f ) { return f; }

然后:

Func( pick_signature<std::ostream&(std::ostream&)>( std::endl ) );

这表明我想做什么,而不是static_cast

也许可以制作第二个版本,它采用类类型和签名,并且也用于方法。 (我不知道如何让它对方法透明地工作,我认为理论上它不能)。

【讨论】:

    猜你喜欢
    • 2012-10-25
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 2019-12-17
    • 2012-11-21
    • 1970-01-01
    • 2016-06-03
    • 1970-01-01
    相关资源
    最近更新 更多