相关疑难解决方法(0)

std :: function的模板参数(签名)是不是它的类型?

鉴于以下代码,模糊性背后的原因是什么?我可以绕过它还是我必须保持(讨厌的)显式演员?

#include <functional>

using namespace std;

int a(const function<int ()>& f)
{
    return f();
}

int a(const function<int (int)>& f)
{
    return f(0);
}

int x() { return 22; }

int y(int) { return 44; }

int main()
{
    a(x);  // Call is ambiguous.
    a(y);  // Call is ambiguous.

    a((function<int ()>)x);    // Works.
    a((function<int (int)>)y); // Works.

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有趣的是,如果我a()function<int ()>参数注释掉函数并a(x)在我的main中调用,则编译正确失败,因为它们之间的类型不匹配xfunction<int (int)>唯一a()可用函数的参数.如果编译器在这种情况下失败,为什么在存在这两个a()函数时会有任何歧义?

我试过VS2010和g ++ v.4.5.两者都给我完全相同的歧义.

c++ c++11 std-function

39
推荐指数
2
解决办法
5696
查看次数

在标准下调用std :: function <void(Args ...)>是违法的吗?

所有报价均来自N3797.

4/3 [转]

当且仅当声明T t = e时,表达式e可以隐式转换为类型T. 对于一些发明的临时变量t而言,其形式良好

这意味着没有表达式可以隐式转换为void,这void t=e对所有表达式都是非法的e.如果e是类型的表达式void,例如,这甚至是真的void(3).

所以类型的表达式void不能隐式转换为void.

这导致我们:

20.9.2/2要求[func.require]

将INVOKE(f,t1,t2,...,tN,R)定义为隐式转换为R的INVOKE(f,t1,t2,...,tN).

总之,INVOKE(f, t1, t2, ..., tN, R)当是永远有效Rvoid,如无(含void)可以隐式转换为void.

因此,所有都std::function<void(Args...)>具有属性!*this,因此不能被调用,因为唯一没有!*this后置条件的构造函数(或者不从function相同类型的另一个复制此类状态)需要Callable其中一个参数.

20.9.11.2/7类模板函数[func.wrap.func]

要求:F应为CopyConstructible.对于参数类型ArgTypes,f应为Callable(20.9.11.2)并返回R类型.A的拷贝构造函数和析构函数不应抛出异常.

20.9.11.2/2类模板函数[func.wrap.func]

类型F的可调用对象f对于参数类型ArgTypes是Callable,如果表达式INVOKE(f,declval()...,R)被认为是未评估的操作数(第5条),则返回类型R( 20.9.2).

如上所述,没有Callable表达std::function<void(Args...)>.

如果以某种方式std::function<void(Args...)>找到这样的地方,调用operator()将会形成错误:

调用[func.wrap.func.inv]

效果:INVOKE(f,std :: forward(args)...,R)(20.9.2),其中f是*this的目标对象(20.9.1).

因为INVOKE(f, …

c++ language-lawyer c++11 std-function c++14

27
推荐指数
1
解决办法
863
查看次数

lambdas的参数和返回值的类型转换规则是什么?

我最近惊讶于lambdas可以被分配给std::function具有略微不同签名的s .略有不同意味着当function指定返回时void,lambda的返回值可能会被忽略,或者参数可能是functionlambda 中的值但是引用.

请参阅此示例(ideone),其中我强调了我怀疑不兼容的内容.我认为返回值不是问题,因为你总是可以调用一个函数并忽略返回值,但是从引用到值的转换看起来很奇怪:

int main() {
    function<void(const int& i)> f;
    //       ^^^^ ^^^^^    ^
    f = [](int i) -> int { cout<<i<<endl; return i; };
    //     ^^^    ^^^^^^
    f(2);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

小问题是:为什么这段代码编译和工作?主要问题是:与lambda参数和返回值一起使用时,类型转换的一般规则是什么std::function

c++ lambda type-conversion c++11

21
推荐指数
1
解决办法
804
查看次数

std :: function赋值应该忽略返回类型吗?

根据C++ 11或C++ 14标准,代码是否在有效的C++下面?

#include <functional>

int ReturnInt()
{
  return 5;
}

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

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

我发现这个其他堆栈溢出问题表明它应该工作.

c++ c++11 std-function c++14

6
推荐指数
1
解决办法
1143
查看次数

为什么不起作用阻止不同返回类型的施工?

std::function 允许你这样做:

std::function<void()> = []()->int{return 42;};
Run Code Online (Sandbox Code Playgroud)

但不是这个:

std::function<void()> = [](int i)->int{return 42;};
Run Code Online (Sandbox Code Playgroud)

大概是因为返回类型不是函数签名的一部分.但是std::function是一个类类型,它被赋予一个返回类型,并且知道它构造的函数对象的返回类型.所以这里可能存在编译器错误.

为什么没有编译器错误?

c++

5
推荐指数
1
解决办法
93
查看次数

如何将可变参数模板参数绑定到函数

我正在尝试模仿 std::thread 构造函数功能:

template< class Function, class... Args > 
explicit thread( Function&& f, Args&&... args );
Run Code Online (Sandbox Code Playgroud)

我试过使用调试器来查看它是如何工作的,但我无法弄清楚。

如何像线程的构造函数那样创建和存储绑定类型?

像这样(语法可能错误):

class myClass{
private:
auto bindType;

public:
template< class Function, class... Args > 
explicit myClass( Function&& f, Args&&... args ) : bindType(somehowBind(f, args) {}
void evaluate() {bindType();}
};
Run Code Online (Sandbox Code Playgroud)

用法示例:

int test(int i) {return i;}

int main(){
myClass my(test, 5);
my.evaluate();
}
Run Code Online (Sandbox Code Playgroud)

请注意,我不在乎somehowBind函数是否会忽略返回类型,即它的返回类型可以是 std::function 之类的东西。我不想做的就是了解我如何绑定class... Args到给定的函数f,以便在调用后somehowBind它会像 std::bind 一样。为了澄清我的观点,您可以考虑我想要实现的目标如下:

thread t(test, 5); // unlike the usual …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

4
推荐指数
1
解决办法
2599
查看次数

如果 C++11 lambda 返回错误类型,则不会出现 clang 警告或错误

如果 lambda 的返回类型不匹配,看起来我的 clang 编译器 (3.3) 不会生成任何错误:

#include <functional>
typedef std::function<void()> voidFunc;

void foo(voidFunc func) 
{
    func();
}

int main() 
{
    int i = 42;
    foo([i]()
    {
        return i;
    });
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译此代码不会显示任何错误:

clang++ -c -Xclang -stdlib=libc++ -std=c++11 -Weverything -Wno-c++98-compat -Wno-missing-prototypes -o foo.o foo.cpp
Run Code Online (Sandbox Code Playgroud)

如何针对此类问题生成类型错误?

编辑:

这会产生类型错误:

#include <functional>

struct A {};
struct B {};

typedef std::function<A()> aFunc;

void foo(aFunc func)
{
    func();
}

int main()
{
    int i = 42;
    foo([i]() 
    {
        return B();
    });
    return 0;
} …
Run Code Online (Sandbox Code Playgroud)

c++ lambda types clang c++11

4
推荐指数
1
解决办法
1300
查看次数