V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
aigebiu
V2EX  ›  C

在学 C++ 有个问题

  •  
  •   aigebiu · Mar 7, 2016 · 2743 views
    This topic created in 3704 days ago, the information mentioned may be changed or developed.

    void foo() {}

    thread(&foo);
    结果报错 error: ‘ foo ’ declared as reference but not initialized

    a = thread(&foo);
    把它赋给一个 thread 类型变量 a ,就编译通过了

    或者
    thread a(&foo);
    也能通过

    为什么呢?谢谢

    21 replies    2016-03-08 20:48:58 +08:00
    aigebiu
        1
    aigebiu  
    OP
       Mar 7, 2016
    又试了下 thread(&foo).join() 也能过 好像只要把初始化好的 thread 对象用在任何一个地方 (赋值右边,调用方法) 就能过……
    bengol
        2
    bengol  
       Mar 7, 2016 via Android
    贴编译器版本
    aigebiu
        3
    aigebiu  
    OP
       Mar 7, 2016
    @bengol gcc version 4.8.4
    patrickstar
        4
    patrickstar  
       Mar 7, 2016
    不是直接 std::thread(foo)就可以了吗,为啥子在函数名 foo 前加个&
    aigebiu
        5
    aigebiu  
    OP
       Mar 7, 2016
    诶我好像明白错误提示的意思了。。
    编译器把它解释为 thread &foo; 了 声明一个引用但没初始化 所以报错。。

    error: ‘ foo ’ declared as reference but not initialized
    thread &foo;

    error: ‘ foo ’ declared as reference but not initialized
    thread(&foo);

    那么问题就变成了 为什么会解析成声明呢?
    aigebiu
        6
    aigebiu  
    OP
       Mar 7, 2016
    @patrickstar 嗯 是…… 但是显式地取地址也可以吧?
    aigebiu
        7
    aigebiu  
    OP
       Mar 7, 2016
    难道类(变量) 也是一种声明变量的方式?
    比如 string(a); 也能过 得到一个空字符串 a (之前没声明 a )
    patrickstar
        8
    patrickstar  
       Mar 7, 2016
    一般情况下函数名本身就是一个指针,再取地址就是指针的指针,不是 std::thread() 需要的参数
    aigebiu
        9
    aigebiu  
    OP
       Mar 7, 2016
    @patrickstar 可是&后也能正常运行啊 函数指针取不取地址应该是一样的(只有在访问成员函数时好像有区别)

    贴个 stackoverflow 上的答案( http://stackoverflow.com/questions/4298654/operator-optional-in-function-pointer-assignment

    Operator & is indeed optional when taking the address of a function in your context (assigning it to something). It is not compiler-specific, it follows from the formal definition of the language.

    Symmetrically, operator * is optional when invoking the function through a pointer. In your example, you could invoke the function as either (*logfunc)(n) or logfunc(n). You used the latter, but the former would work as well.
    ffffwh
        10
    ffffwh  
       Mar 7, 2016 via Android
    C++语法二义性很多的。
    这种情况会优先判为 declaration 而不是函数调用,好在一般都有编译器 warning
    matthewgao
        11
    matthewgao  
       Mar 7, 2016 via Android
    你这里还有个问题,如果你只写 thread(foo),那么你生成的这个 thread 对象就是个右值对象,没有任何产量标识它,那么它一旦 go out of scope 那么就会 segmentalfault, 但是你写 thread(foo).join 会阻塞主进程,所以线程会正常运行
    aigebiu
        12
    aigebiu  
    OP
       Mar 7, 2016
    @matthewgao 哦 谢谢 那 c ++里有没有像 go 语言里的 go 那样的轻量级并发呢?我是一个线程不断读数据 然后动态创建若干线程处理数据 是不是只能维护一个线程池 主线程终止时统一 join 呢?

    @ffffwh 为什么会优先判为 declaration ?有没有这方面资料、书推荐呢?谢谢
    vanxining
        13
    vanxining  
       Mar 7, 2016
    学习了。我想应该是语法优先级的问题。就像 C++11 之前的 vector<vector<int>>以及 Foo foo(int);这样的情况一样。
    bombless
        14
    bombless  
       Mar 7, 2016 via Android
    噗 c++本身是不支持嵌套的函数定义的,所以本身函数调用和函数定义是不会在一个层次里出现的。
    你这个是 gcc 扩展。
    vanxining
        15
    vanxining  
       Mar 7, 2016
    @vanxining 想了想,令人容易搞错的这种形式:
    Foo bar();。
    这是一个函数声明还是定义了一个 Foo 实例?
    congeec
        16
    congeec  
       Mar 7, 2016
    @patrickstar 函数名就是函数指针,加个取地址符号&还是函数指针。这是特例
    xuboying
        17
    xuboying  
       Mar 7, 2016 via Android
    插个楼,这里的函数可以用 lambda 定义么?
    aigebiu
        18
    aigebiu  
    OP
       Mar 7, 2016
    @bombless 我用 clang 编译也是同样的错诶 我觉得还是把&判断成声明引用了
    matthewgao
        19
    matthewgao  
       Mar 8, 2016 via Android
    @xuboying 当然可以啦
    matthewgao
        20
    matthewgao  
       Mar 8, 2016 via Android
    @aigebiu 这个看你具体需求了,不 join detach 也可以,如果你这一堆线程都只干这一个事
    bombless
        21
    bombless  
       Mar 8, 2016 via Android
    @aigebiu clang 和 gcc 是兼容的。主楼说的没什么错,我是说普通编译器并不会遇到这个问题,而会在别的地方报错。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5831 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 124ms · UTC 06:32 · PVG 14:32 · LAX 23:32 · JFK 02:32
    ♥ Do have faith in what you're doing.