c++ - std::in_place_t 和 C++17 中的 friend

标签 c++ language-lawyer c++17

截至撰写本文时,cppreference 给出了 reasonably simple definition 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{};

但是,C++17 标准的最新草案 linked from isocpp.org有一个更复杂的定义(第 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>);

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

  • 哪个版本是正确的,Issaqua 之后(2016 年 11 月)? (大概是第二个吧,不过有可能N4606在最近一次 session 之后还没有更新,cppreference已经更新了。)

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

  • 最重要的是,谁能解释第二个版本的工作原理?示例实现是什么样的?

最佳答案

第一个版本目前是正确的,并且很可能是最终在 C++17 中的版本。

第二个版本是 an attempt允许一个人写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);

使这种语法工作的唯一方法是使 in_place一个重载的函数,这也需要使 in_place*_t引用函数的别名。否则没有真正的实现差异 - in_place函数并不是要被调用的,它们的存在只是为了让对它们的引用可以作为标签传递并匹配相应的 _t类型。

尽管如此,它还是太聪明了,并引起了自己的问题(例如,与普通标签类型不同,它们对 decay 的响应不好,而普通的 std::in_place 是一个重载的函数名称,行为不端完美转发器:std::optional<std::optional<int>> o(std::in_place, std::in_place); 不起作用,因为编译器无法解析第二个 std::in_place ),所以 it got backed out在伊瑟阔,现在你必须写

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);

不那么漂亮,但更理智。

关于c++ - std::in_place_t 和 C++17 中的 friend ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40923097/

相关文章:

c++ - 关于指针 C++ 的困惑

c++ - 如何减少 C++ 中多重集中元素的数量?

c++ - 任何人都有一个很好的 C++ 共享内存容器?

c++ - 当 `sleep_until()` 指定过去的时间点时,行为是否明确?

c++ - 期望引入类型(枚举类)的成员函数的缩写参数

c++ - 从计数错误的文件中读取数据。读取数据的最佳做法是什么?

c++ - 通过第一个元素推断初始值设定项列表的类型

c++ - volatile 未按预期工作

c++ - 更改删除顺序以删除变量之前的指针

c++ - 为什么不允许 std::variant 与其替代类型之一进行相等比较?