我试图通过给它一个可以构造其
std::variant<Ts...>
之一的值来理解 Ts
的构造。 参考资料说
std::变体
::变体 ...
(4)
template<class T> constexpr variant(T&& t) noexcept(/* see below */);
...
(4) 转换构造函数。构造一个包含 替代类型
将由重载决策选择 如果存在过载,则表达式T_j
F(std::forward<T>(t))
中每个
F(T_i)
的虚函数T_i
,除了 不考虑缩小转换。Types...
正式: 仅当声明
对于某些发明变量
F(T_i)
有效时才考虑重载
T_i x[] = { std::forward<T>(t) };
。x
从这个片段中,我预计以下内容会起作用:
using Var = std::variant<uint32_t, uint64_t>; // alias OK
([](uint32_t){})(std::forward<uint8_t>(12)); // compiles fine --> imaginary function F can be called
uint32_t x[] = {std::forward<uint8_t>(12)}; // compiles fine --> array declaration is valid
static_assert(std::is_constructible_v<Var, uint8_t>); // assertion fails
但事实并非如此(断言失败)。是因为
uint32_t
和 uint64_t
之间的歧义都可以用 uint8_t
构造吗?我在 cppreference 链接中没有找到任何相关信息(也许我是瞎子)。
哦,现在我盯着我链接的段落,答案显然是“是”,这是因为含糊不清。该参考文献指出,如果所有
F(uint32_t)
都存在过载 ,则应选择 Ts
。确实,如果有F(uint32_t)
和 F(uint64_t)
,那么前者就不会被选中!