为什么会有std::this_thread命名空间?

4

为什么要使用std::this_thread命名空间?可不可以将该命名空间中的成员实现为std::thread类的静态成员?

1个回答

15

原始提案中,无论你是为自己还是为子线程获取thread::id,获取的方式都是通过get_id()来实现:

请注意使用this_thread命名空间以消除在请求当前线程的ID与子线程的ID时的歧义。在接口概念上保持一致性,此操作的get_id名称保持不变。

std::thread my_child_thread(f);
typedef std::thread::id ID;

ID my_id = std::this_thread::get_id();  // The current thread's id
ID your_id = my_child_thread.get_id();  // The child   thread's id

因此,this_thread 命名空间是一种可读性强的方式来区分两个线程,同时保持概念接口最小化(获取线程 ID 的名称相同)。

以下是可能的替代设计:

struct thread
{
    static int get_id() {return 1;}
    int get_id() const {return 2;}
};

这种设计的一个缺点是它无法编译:
test.cpp:4:9: error: static and non-static member functions with the same parameter types cannot be overloaded
    int get_id() const {return 2;}
        ^
test.cpp:3:16: note: previous declaration is here
    static int get_id() {return 1;}
               ^
1 error generated.

另一种设计方式会给静态成员起不同的名称。但现在接口更大了。原始提案也以完全相同的方式处理了另一个函数:

bool have_i_been_canceled = std::this_thread::cancellation_requested();  // Current thread's cancellation status
bool have_you_been_canceled = my_child_thread.cancellation_requested();  // Child   thread's cancellation status

因此,重复使用名称让客户端不必学习那么多名称是很有意义的。他们只需要学会使用this_thread命名空间来查询当前线程即可。不幸的是,在标准化过程中,委员会取消了线程取消。

谢谢,但是my_child_thread.get_id()怎么可能会有歧义呢?我想我在这里正在寻找一个现实生活中的例子。我知道这很难要求。 - user2100815
@user2100815,不是模棱两可,而是“不起作用”。如果get_id是获取当前线程ID的静态成员函数,则my_child_thread.get_id()调用该静态成员函数。请参见http://codepad.org/JRTvzDLk以获取简化示例。(顺便说一句,这不是我自己想出来的,有人在一个小时前的评论中写了这个!) - user395760
1
@user2100815 给我们举个例子,说明你会用其他方法来完成它。 - Seth Carnegie
@Seth,你似乎认为我在批评标准库。相反,我正在努力理解它。 - user2100815
3
@user2100815 我知道你是,如果你认为我在批评你,那你是错的。我也想要理解这个问题。我只是提供了我的意见,它不值得一提,只是一些编码字节而已。当我向你要一个例子时,是因为你问如何让它变得有歧义,但除非你决定用另一种方式,否则它是不可能有歧义的。 - Seth Carnegie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接