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

st-d::f命令赋值应该忽略返回类型吗?[重复]

韦高格
2023-03-14

根据C 11或C 14标准,以下代码是否有效C?

#include <functional>

int ReturnInt()
{
  return 5;
}

int main( int argc, char **argv )
{
  std::function< void () > BoundType = ReturnInt;
  return 0;
}

该代码可以使用最新的cygwin版本的gcc(4.8.3)和clang(4.3.2)进行编译,但不适用于Visual Studio 2013、Visual Studio 2013 11月CTP或Visual Studio 14预览版。如果std::function更改为boost::function,它也可以在所有平台上编译。

我发现了另一个堆栈溢出问题,这表明它应该有效。

共有2个答案

张兴旺
2023-03-14

C 11和14中的std::function没有您想要的行为。

它也无法检测严重的过载。

我们可以将其包装在不同的类型中,该类型既具有您想要的行为(val丢弃返回),又具有SFINAE错误过载检测,而我们如下所示:

template<class Sig>
struct checked_function;

template<class R, class... Args>
struct checked_function<R(Args...)>:std::function<R(Args...)> {
  using function = std::function<R(Args...)>;
  checked_function(std::nullptr_t):function() {}
  checked_function():function() {}
  template<class F, class=typename std::enable_if<
    std::is_convertible<
      typename std::result_of< F(Args...) >::type
      , R
    >::value
  >::type>
  checked_function( F&& f ):function( std::forward<F>(f) ) {}

  template<class F, class=typename std::enable_if<
    std::is_convertible<
      typename std::result_of< F(Args...) >::type
      , R
    >::value
  >::type>
  checked_function& operator=( F&& f ) { return function::operator=( std::forward<F>(f) ); }

  checked_function& operator=( checked_function const& o ) = default;
  checked_function& operator=( checked_function && o ) = default;
  checked_function( checked_function const& o ) = default;
  checked_function( checked_function && o ) = default;
};

template<class... Args>
struct checked_function<void(Args...)>:std::function<void(Args...)> {
  using function = std::function<void(Args...)>;
  checked_function(std::nullptr_t):function() {}
  checked_function():function() {}
  template<class F, class=typename std::enable_if<
    std::is_same<
      typename std::result_of< F(Args...) >::type
      , void
    >::value
  >::type>
  checked_function( F&& f, int*unused=nullptr ):function( std::forward<F>(f) ) {}

  template<class F>
  static auto wrap(F&& f){
    return [f_=std::forward<F>(f)](auto&&...args){
      f_( std::forward<decltype(args)>(args)... );
    };
  }
  template<class F, class=typename std::enable_if<
    !std::is_same<
      typename std::result_of< F(Args...) >::type
      , void
    >::value
  >::type>
  checked_function( F&& f, void*unused=nullptr ):
    function( wrap(std::forward<F>(f)) ) {}

   template<class F>
  typename std::enable_if<
    !std::is_same<
      typename std::result_of< F(Args...) >::type
      , void
    >::value,
    checked_function&
  >::type operator=( F&& f ) { return function::operator=( wrap(std::forward<F>(f)) ); }

  template<class F>
  typename std::enable_if<
    std::is_same<
      typename std::result_of< F(Args...) >::type
      , void
    >::value,
    checked_function&
  >::type operator=( F&& f ) { return function::operator=( std::forward<F>(f) ); }

  checked_function& operator=( checked_function const& o ) = default;
  checked_function& operator=( checked_function && o ) = default;
  checked_function( checked_function const& o ) = default;
  checked_function( checked_function && o ) = default;
};

它现在在C 14中编译(不是在C 11中,因为wrapwrap可以在调用时用它自己的主体的副本替换,所以…)。可能会把样板文件减少很多。

它使用了一些C14特性(精确地说,在wrap中,可以使用lambda——您可以通过添加更多样板文件来消除这一点)。

还没跑。

宗增
2023-03-14

代码在C 11中是未定义的行为,在C 14中格式错误。C 14将此备注添加到此构造函数的规范中:

备注:这些构造函数不应参与重载解析,除非f对于参数类型ArgTypes...和返回类型R是Callable(20.9.11.2)。

可调用在[func.wrap.func]/p2中定义:

类型为f的可调用对象f可用于参数类型ArgTypes,如果表达式调用(f,declval),则返回类型为R

要使此调用格式良好,不带R的调用的返回类型必须隐式转换为R([func.require]/p2)。

在C 11中,这些语句是在Requry子句下的,这意味着由客户端来正确处理它们,如果客户端失败,任何事情都可能发生,包括成功编译。

LWG 2132改变了这一点。

 类似资料:
  • 问题内容: 我到底应该输入什么? 测试?这样的东西,?运行模块时不需要什么(自述文件除外)? 我对此没有任何指导。 问题答案: 正如您可能发现的那样,NPM并没有具体说明应该放入的内容,而是有一个默认忽略文件列表。许多人甚至不使用它,因为如果不存在,默认情况下会忽略其中的所有内容。此外,默认情况下,无论设置如何,许多文件都将被忽略,并且某些文件总是会被忽略,如上面的链接所述。 关于应该永远存在的东

  • Java 8中引入的类型对于很多开发人员来说是一个新鲜事物。 返回类型的getter方法代替经典的是一个好的实践吗?假设值可以是。

  • 本文向大家介绍system.reactive 忽略重复值,包括了system.reactive 忽略重复值的使用技巧和注意事项,需要的朋友参考一下 示例 有两个用于过滤重复项的运算符: 您还可以传递谓词:            

  • 我目前正在学习Spring boot,我一直在测试一个项目——非常感谢任何帮助,因为我是这里的初学者。 我有一个rest控制器测试,使用Mockito,当使用Mockito.when()调用方法时,该测试似乎忽略了Then返回。 这是整个班级: 名为“testCreateUser”的测试没有问题地通过了。给我一个问题的是名为“testFindUserById”的测试。 以下是我尝试测试的控制器方法

  • 问题内容: 我正在使用以下选项 在bash脚本中停止执行错误。我有大约100行脚本正在执行,并且我不想检查脚本中每一行的返回码。 但是对于一个特定的命令,我想忽略该错误。我怎样才能做到这一点? 问题答案: 解决方案: 例: 将永远不会打印。 另外,我想补充一点,当打开时,如果管道中的命令之一具有非零退出代码(关闭该命令必须是最后一个),shell认为整个管道具有非零退出代码就足够了。

  • 我看过返回IList vs ICollection vs Collection以及它链接的其他问题,但我仍然对这个问题感到困惑。 出于演示目的,我们假设我有一个类,在其中公开了一个公共方法,如下所示: 要遵循CA1002,我的方法应该返回实际的集合类(、等)或它们的接口(、等),如果我希望返回具体?