1."坑"的问题是什么?
先看一段代码:
class Functor { public: void operator()() { std::cout << "我是线程的初始函数" << std::endl; } }; int main() { std::thread t(Functor());// 强制高速编译器这是一个构造函数! t.join(); return 0; }
讯享网
按照正常的思路分析这段代码应该是这样的:
Functor类当中有一个"operator()"成员函数,这就注定Functor类对象是一个可调用对象(当成函数一样使用)。那么在"std::thread t(Functor())"当中,t的构造函数的参数是一个Functor类的匿名对象,也就相当于传递了一个线程的初始函数。这句代码之后,输出结果应该为"我是线程的初始函数"才对。
但是这段代码的结果却是:
啥玩意???竟然报错!!??后面反复编译了几次,依然是这个结果。这就让我陷入了沉思......
实际上"std::thread t(Functor())"被编译器解释成了一个函数声明。即,一个函数名为t,返回类型为std::thread,参数为函数指针(指向一个无参的,返回类型为Functor的函数)。
2.从另一个角度去看"坑"
先看这么一段代码:
讯享网int main() { std::vector<int> vec(std::string()); return 0; }
放心,不报错,并且编译过。
它也被解释成了函数声明。问题就在于,它为什么被解释成一个函数声明?

如果我把它写成这样:
int main() { //std::vector<int> vec(std::string()); std::vector<int> func(std::string p()); return 0; }
是不是就清楚多了?如果还不清楚,我再这样写一段代码:
讯享网int main() { //std::vector<int> vec(std::string()); std::vector<int> func(std::string p()); return 0; } std::string p() { return ""; }
清楚了吧!func后面的括号写的是一个函数。也就说,"std::vector<int> func(std::string p());"是一个函数声明,返回值为std::vector<int>,参数类型为一个函数指针(指向一个返回类型为std::string、无参的函数)。
再回看"std::vector<int> vec(std::string());"这句话,需要注意一个细节,那就是函数声明的形参类型可以不用给名字。这就透了吧!
还有一个问题,"std::vector<int> vec(std::string());"当中的"(std::string())"明明是一个函数,我为什么要说它是一个函数指针?这里又涉及到一个细节,在C/C++中,没有函数类型,这里的"(std::string())"会自动被解析成指针!
如果还不理解,看这么一段代码:
void test(int arr[]);
test函数接收的形参真的是一个数组吗?当然不是咯,这里的arr是一个指针!
3.解决方法
所以在C++11当中又补充了一个"初始化列表",像下面这么用:
讯享网class Functor { public: void operator()() { std::cout << "我是线程的初始函数" << std::endl; } }; int main() { std::thread t{Functor()};// 强制告诉编译器这是一个构造函数! t.join(); return 0; }
所以最终的输出结果就是正确的咯!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/23315.html