在学 C++ 有个问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
aigebiu
V2EX    C

在学 C++ 有个问题

  •  
  •   aigebiu 2016-03-07 19:39:46 +08:00 2450 次点击
    这是一个创建于 3507 天前的主题,其中的信息可能已经有所发展或是发生改变。

    void foo() {}

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

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

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

    为什么呢?谢谢

    21 条回复    2016-03-08 20:48:58 +08:00
    aigebiu
        1
    aigebiu  
    OP
       2016-03-07 19:43:37 +08:00
    又试了下 thread(&foo).join() 也能过 好像只要把初始化好的 thread 对象用在任何一个地方 (赋值右边,调用方法) 就能过……
    bengol
        2
    bengol  
       2016-03-07 19:55:18 +08:00 via Android
    贴编译器版本
    aigebiu
        3
    aigebiu  
    OP
       2016-03-07 19:58:28 +08:00
    @bengol gcc version 4.8.4
    patrickstar
        4
    patrickstar  
       2016-03-07 20:02:35 +08:00
    不是直接 std::thread(foo)就可以了吗,为啥子在函数名 foo 前加个&
    aigebiu
        5
    aigebiu  
    OP
       2016-03-07 20:02:35 +08:00
    诶我好像明白错误提示的意思了。。
    编译器把它解释为 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
       2016-03-07 20:06:31 +08:00
    @patrickstar 嗯 是…… 但是显式地取地址也可以吧?
    aigebiu
        7
    aigebiu  
    OP
       2016-03-07 20:10:06 +08:00
    难道类(变量) 也是一种声明变量的方式?
    比如 string(a); 也能过 得到一个空字符串 a (之前没声明 a )
    patrickstar
        8
    patrickstar  
       2016-03-07 20:11:46 +08:00
    一般情况下函数名本身就是一个指针,再取地址就是指针的指针,不是 std::thread() 需要的参数
    aigebiu
        9
    aigebiu  
    OP
       2016-03-07 20:16:31 +08:00
    @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  
       2016-03-07 20:50:06 +08:00 via Android
    C++语法二义性很多的。
    这种情况会优先判为 declaration 而不是函数调用,好在一般都有编译器 warning
    matthewgao
        11
    matthewgao  
       2016-03-07 20:51:41 +08:00 via Android
    你这里还有个问题,如果你只写 thread(foo),那么你生成的这个 thread 对象就是个右值对象,没有任何产量标识它,那么它一旦 go out of scope 那么就会 segmentalfault, 但是你写 thread(foo).join 会阻塞主进程,所以线程会正常运行
    aigebiu
        12
    aigebiu  
    OP
       2016-03-07 21:00:05 +08:00
    @matthewgao 哦 谢谢 那 c ++里有没有像 go 语言里的 go 那样的轻量级并发呢?我是一个线程不断读数据 然后动态创建若干线程处理数据 是不是只能维护一个线程池 主线程终止时统一 join 呢?

    @ffffwh 为什么会优先判为 declaration ?有没有这方面资料、书推荐呢?谢谢
    vanxining
        13
    vanxining  
       2016-03-07 21:05:42 +08:00
    学习了。我想应该是语法优先级的问题。就像 C++11 之前的 vector<vector<int>>以及 Foo foo(int);这样的情况一样。
    bombless
        14
    bombless  
       2016-03-07 21:44:38 +08:00 via Android
    噗 c++本身是不支持嵌套的函数定义的,所以本身函数调用和函数定义是不会在一个层次里出现的。
    你这个是 gcc 扩展。
    vanxining
        15
    vanxining  
       2016-03-07 22:10:03 +08:00
    @vanxining 想了想,令人容易搞错的这种形式:
    Foo bar();。
    这是一个函数声明还是定义了一个 Foo 实例?
    congeec
        16
    congeec  
       2016-03-07 22:26:33 +08:00
    @patrickstar 函数名就是函数指针,加个取地址符号&还是函数指针。这是特例
    xuboying
        17
    xuboying  
       2016-03-07 22:29:19 +08:00 via Android
    插个楼,这里的函数可以用 lambda 定义么?
    aigebiu
        18
    aigebiu  
    OP
       2016-03-07 22:58:07 +08:00
    @bombless 我用 clang 编译也是同样的错诶 我觉得还是把&判断成声明引用了
    matthewgao
        19
    matthewgao  
       2016-03-08 00:15:28 +08:00 via Android
    @xuboying 当然可以啦
    matthewgao
        20
    matthewgao  
       2016-03-08 00:18:47 +08:00 via Android
    @aigebiu 这个看你具体需求了,不 join detach 也可以,如果你这一堆线程都只干这一个事
    bombless
        21
    bombless  
       2016-03-08 20:48:58 +08:00 via Android
    @aigebiu clang 和 gcc 是兼容的。主楼说的没什么错,我是说普通编译器并不会遇到这个问题,而会在别的地方报错。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2759 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 15:08 PVG 23:08 LAX 08:08 JFK 11:08
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86