Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在C++;11?_C++_C++11_Visual C++_C++17 - Fatal编程技术网

C++ 如何在C++;11?

C++ 如何在C++;11?,c++,c++11,visual-c++,c++17,C++,C++11,Visual C++,C++17,我正在寻找的代码如下所示 bool Func1(int Arg1, C++11LambdaFunc Arg2){ if(Arg1 > 0){ return Arg2(Arg1); } } 稍后我将使用此代码 Func1(12, [](int D) -> bool { ... } ); 第一个解决方案: 您可以将Func1()函数设置为函数模板: 同样,这将允许您按所需方式调用Func1(): int main() { Func1(12, [

我正在寻找的代码如下所示

bool Func1(int Arg1, C++11LambdaFunc Arg2){
    if(Arg1 > 0){
        return Arg2(Arg1);
    }
}
稍后我将使用此代码

Func1(12, [](int D) -> bool { ... } );

第一个解决方案:

您可以将
Func1()
函数设置为函数模板:

同样,这将允许您按所需方式调用
Func1()

int main()
{
    Func1(12, [](int D) -> bool { return D < 0; } );
}
int main()
{
    Func1(12, [](int D) -> bool { return D < 0; } );
}
intmain()
{
Func1(12,[](int D)->bool{return D<0;});
}

基本版本,用于头文件:

template<typename Lambda>
bool Func1(int Arg1, Lambda Arg2){ // or Lambda&&, which is usually better
  if(Arg1 > 0){
    return Arg2(Arg1);
  } else {
    return false; // remember, all control paths must return a value
  }
}

通过从
std::function
中删除所有权语义,只需键入擦除调用,这样就不需要从
std::function
中进行任何分配

第一个示例的一个奇特版本,它还可以更好地处理一些角点情况:(还必须在头文件中实现,或者在使用的同一翻译单元中实现)

模板
布尔函数1(整数Arg1、Lambda和Arg2){
如果(Arg1>0){
返回标准::转发(Arg2)(Arg1);
}否则{
return false;//记住,所有控制路径都必须返回一个值
}
}
它使用了一种称为“完美转发”的技术。对于某些函子,这会生成与#1稍有不同的行为(通常是更正确的行为)

大部分改进来自于在参数列表中使用
&
:这意味着传入了对函子的引用(而不是副本),节省了一些成本,并允许传入
常量
或非
常量
函子

>代码> STD::OpDebug(…)>代码>更改只会导致行为改变,如果某人使用了一种新的C++特性,允许方法(包括<代码>操作程序)>代码>重写<代码>这个//Cux>指针的rVals/LValk状态。从理论上讲,这可能是有用的,但是我看到的基于

this
的右值状态的实际覆盖的函子数量是
0
。当我在编写严肃的库代码(tm)时,我会遇到这种麻烦,但很少有其他的麻烦

还有一个可能要考虑的事情。假设您想要获取一个返回
bool
的函数,或者一个返回
void
的函数,如果该函数返回
void
,您想要将其视为返回
true
。例如,您使用的函数是在对某个集合进行迭代时调用的,并且您希望有选择地支持早期停止。当函数想要提前停止时,返回
false
,否则返回
true
void

或者,在更一般的情况下,如果一个函数有多个重写,其中一个重写接受一个函数,而其他重写在同一位置接受其他类型的重写

这是可能的,这是我在这里要讨论的(使用智能适配器或通过SFINAE技术)。但是,您最好只创建两个不同的命名函数,因为所需的技术太重了



1从技术上讲,
std::function
可以使用magic fairy dust来完成它所做的事情,因为它的行为是由标准描述的,而不是它的实现。我正在描述一个简单的实现,它近似于我与之交互的
std::function
实现的行为。

对于那些品味更传统的人,请注意,非捕获lambda可以转换为函数指针。因此,您可以将上述函数编写为:

bool Func1(int Arg1, bool (*Arg2)(int)) { ... }

对于传统功能lambdas,它都能正常工作。

+1:4秒太慢了。从技术上讲,您应该使用std::forward(Arg2)(Arg1),但这几乎不值得费心。@Yakk:嗯,我想在调用lambda或函数时这不会有什么区别,对吗?毕竟你没有转发任何东西。如果函子使用了对
this
(作为函数限定符,我的意思是
操作符()(…)&&
)的引用,那么它可能与函子有所不同-但是。。。呵呵,不值得打扰IMO:)理论上,无论是
[myvec](intx){myvec.push_back(x);return myvec;}
还是手动等效工具都可以意识到它是在
右值环境中评估的,并通过移动返回。但是是的,它是非常模糊的。@AndyProwl为什么不向前看呢?即使这对于这个简单的例子来说可能并不重要,但最好使用forward@balki:具体来说,它在这种情况下没有任何区别-如果没有区别,我更喜欢可读性更强的版本。使用模板可以捕获函数指针、函数引用、函数对象、,lambdas(带或不带捕获)、std::函数、std::bind的结果等。如果要传递预先存在的函数或需要与C代码进行互操作,则使用模板也不起作用。没有真正感兴趣的C++纯度方面的论点;这只是我认为被现有答案遗漏的语言的一部分。我得到了C接口参数,但模板将完全绑定到一个预先存在的函数。如果你的对象可以像函数一样被调用,那么模板就可以工作了。我相信你也可以像“const std::function&func”一样传递函数。这比搬家和搬家好/坏吗?我一直认为“const&”意味着只是“传递这个对象”,但&&意味着将对象状态移动到一个新实例(可能称为move copy ctor?)@AlexPetrenko
&
通常是一个右值引用,但它也用于名为/(pass this object)的技术中,
T&
可以是右值引用或左值引用(在类型推断上下文中——从技术上讲,在任何地方,但很少以这种方式在类型推断之外使用)。
template<typename Lambda>
bool Func1(int Arg1, Lambda Arg2){ // or Lambda&&, which is usually better
  if(Arg1 > 0){
    return Arg2(Arg1);
  } else {
    return false; // remember, all control paths must return a value
  }
}
bool Func1(int Arg1, std::function<bool(int)> Arg2){
  if(Arg1 > 0){
    return Arg2(Arg1);
  } else {
    return false; // remember, all control paths must return a value
  }
}
template<class Sig>
struct function_ref;

template<class R, class...Args>
struct function_ref<R(Args...)> {
  R operator()(Args...args) const {
    return pf(state, std::forward<Args>(args)...);
  }
  function_ref()=default;
  function_ref(function_ref const&)=default;
  function_ref& operator=(function_ref const&)=default;
  explicit operator bool()const{ return pf!=nullptr; }

  // this overload reduces indirection by 1 step
  // and allows function_ref<Sig> to resolve overloads
  // on an overload set sometimes.
  function_ref( R(*f)(Args...) ):
    pf([](State const& state, Args&&...args)->R{
      return reinterpret_cast<R(*)(Args...)>(state.pfunstate)(std::forward<Args>(args)...);
    })
  {
    state.pfunstate = reinterpret_cast<void(*)()>(f);
  }

  // this grabs anything callable (that isn't this own type)
  // and stores a pointer to it to call later.
  template<class F>
  requires (
    std::is_convertible_v<
      std::invoke_result_t< std::remove_reference_t<F>, Args... >, R
    >
    && !std::is_same_v< std::decay_t<F>, function_ref >
  )
  function_ref( F&& f ):
    pf([](State const& state, Args&&...args)->R{
      return (*(std::remove_reference_t<F>*)state.pstate)(std::forward<Args>(args)...);
    })
  {
    state.pstate = std::addressof(f);
  }
private:
  union State {
    void* pstate = nullptr;
    void(*pfunstate)();
  };
  State state;
  R(*pf)(State const&, Args&&...) = nullptr;
};
// a deduction guide permitting function_ref{foo} to work
// if foo is a non-overloaded function name.
template<class R, class...Args>
function_ref( R(*)(Args...) )->function_ref<R(Args...)>;
template<typename Lambda>
bool Func1(int Arg1, Lambda&& Arg2){
  if(Arg1 > 0){
    return std::forward<Lambda>(Arg2)(Arg1);
  } else {
    return false; // remember, all control paths must return a value
  }
}
bool Func1(int Arg1, bool (*Arg2)(int)) { ... }