std :: in_place_t和C++中的朋友17

Tri*_*dle 17 c++ language-lawyer c++17

截至撰写本文时,cppreference给出了一个相当简单std::in_place_t家族定义:

struct in_place_t {
    explicit in_place_t() = default;
};
inline constexpr std::in_place_t in_place{};

template <class T>
struct in_place_type_t {
    explicit in_place_type_t() = default;
};

template <class T>
inline constexpr std::in_place_type_t<T> in_place_type{};

template <size_t I> struct in_place_index_t {
    explicit in_place_index_t() = default;
};

template <size_t I>
inline constexpr in_place_index_t<I> in_place_index{};
Run Code Online (Sandbox Code Playgroud)

但是,从isocpp.org链接的最新C++ 17标准草案有一个相当复杂的定义(第20.2.7节,第536页):

struct in_place_tag {
    in_place_tag() = delete;
};
using in_place_t = in_place_tag(&)(unspecified );

template <class T>
using in_place_type_t = in_place_tag(&)(unspecified <T>);

template <size_t I>
using in_place_index_t = in_place_tag(&)(unspecified <I>);

in_place_tag in_place(unspecified );

template <class T>
in_place_tag in_place(unspecified <T>);

template <size_t I>
in_place_tag in_place(unspecified <I>);
Run Code Online (Sandbox Code Playgroud)

第一个版本简单易懂,但第二个版本对我来说非常不透明.所以,问题:

  • 哪个版本是正确的,在Issaqua之后(2016年11月)?(可能是第二个,但是在最新的会议和cppreference之后,N4606可能还没有更新.)

  • 显然,这在某个时间点发生了变化; 有没有人提到一篇提到变化的论文?

  • 最重要的是,任何人都可以解释第二个版本的工作原理吗?示例实现是什么样的?

T.C*_*.C. 17

目前,第一个版本是正确的版本,并且很可能是以C++ 17结尾的版本.

第二个版本试图允许一个人在in_place任何地方写,没有任何内容,一个类型或一个索引:

std::optional<int> o(std::in_place, 1);
std::any a(std::in_place<int>, 1);
std::variant<int, int> v(std::in_place<0>, 1);
Run Code Online (Sandbox Code Playgroud)

使这种语法有效的唯一方法是创建in_place一个重载函数,并且还需要in_place*_t为函数引用创建别名.否则没有真正的实现差异 - in_place函数不是要调用的,它们只是存在,以便对它们的引用可以作为标记传递并匹配相应的_t类型.

尽管如此,它太聪明并且引起了它自己的问题(例如,与普通标签类型不同,它们不能很好地反应为decay'd,而且简单std::in_place,是一个重载的功能名称,与完美的转发器行为不端:std::optional<std::optional<int>> o(std::in_place, std::in_place);不起作用,因为编译器无法解析第二个std::in_place),所以在Issaquah中被退出,现在你必须写

std::optional<int> o(std::in_place, 1);
std::any a(std::in_place_type<int>, 1);
std::variant<int, int> v(std::in_place_index<0>, 1);
Run Code Online (Sandbox Code Playgroud)

不太漂亮,但更健全.