c – 关于std :: variant提出的界面中的三个构造函数的问题

c – 关于std :: variant提出的界面中的三个构造函数的问题,第1张

概述为什么构建器(4)存在于std :: variant从 http://en.cppreference.com/w/cpp/utility/variant/variant?似乎这将导致在代码中有很多歧义,否则可能会被明确地避免.例如,cppreference上的代码示例强调了用户可能不会注意到的可能的歧义(第三行) variant<string> v("abc"); // OKvariant<st 为什么构建器(4)存在于std :: variant从 http://en.cppreference.com/w/cpp/utility/variant/variant?似乎这将导致在代码中有很多歧义,否则可能会被明确地避免.例如,cppreference上的代码示例强调了用户可能不会注意到的可能的歧义(第三行)
variant<string> v("abc"); // OKvariant<string,string> w("abc"); // ill-formed,can't select the alternative to convert tovariant<string,bool> w("abc"); // OK,but chooses bool

有没有必要的情况呢?

另一个问题是为什么需要同一个cpp参考页面中的构造函数(6)和(8). (5)和(7)是否符合(6)和(8)的目的?我可能会误会他们的用法

对于读者,我在问题中提到的构造函数

constexpr variant();              // (1)    (since C++17)variant(const variant& other);    // (2)    (since C++17)variant(variant&& other);         // (3)    (since C++17)template< class T >               // (4)    (since C++17)constexpr variant(T&& t);template< class T,class... Args >constexpr explicit variant(std::in_place_type_t<T>,Args&&... args); // (5) (since C++17)template< class T,class U,std::initializer_List<U> il,Args&&... args); // (6) (since C++17)template< std::size_t I,class... Args >constexpr explicit variant(std::in_place_index_t<I>,Args&&... args) // (7) (since C++17)template <size_t I,class... Args>constexpr explicit variant(std::in_place_index_t<I>,Args&&... args); // (8) (since C++17)
解决方法

Is there some case where it is absolutely going to be needed?

不,但事情并没有被添加,因为它们是“绝对需要的”.它们被添加,因为它们是有用的.

并且从其一个组件类型隐式转换对于变体非常有用.是的,在某些角落情况下会造成歧义.但是,这种歧义通常是由于类型设计中的缺陷(如字符串字面意思,倾向于通过用户定义的转换转换为bool).

如果有一个模糊的情况,那么你只需要明确.就像使用“abc”的UDL文字而不是裸线字符串(另一个原因).但是当处理精心设计的类型时,没有任何理由强迫大家明确.

Won’t (5) and (7) serve the purposes that (6) and (8) are meant for?

不合理的方式.

在标准的每种情况下,当一个函数使用将被传递给构造函数的可变参数时,它们将使用构造函数语法而不是该对象上的{}语法.所以如果你有这个:

using type = vector<int>;variant<type> t(in_place<type>,6);

你会得到一个调用矢量< int>(6).请注意,这与矢量< int> {6}不同.也就是说,除非您实际通过初始化程序列表,否则您不会获取初始化列表构造函数.

现在,你可以做:

variant<type> t(in_place<type>,initializer_List<int>{6});

但这太过分了.相比之下:

variant<type> t(in_place<type>,{6});

这不算冗长.编译器可以推导出初始化器列表的类型.而如果您尝试将一个支持的初始化列表推导为任意T,则模板参数类型扣除失败.

除了其他方式,模板扣除与auto的推导不同,因为它不会从braced-init-List表达式中推导出initializer_Lists.例如

template <typename Type>voID func(const Type&);

不会将类型推定为以下调用的std :: initializer_List

func({1,2,3,4,5});

有关更多信息,请参见Universal references and std::initializer_list.

总结

以上是内存溢出为你收集整理的c – 关于std :: variant提出的界面中的三个构造函数的问题全部内容,希望文章能够帮你解决c – 关于std :: variant提出的界面中的三个构造函数的问题所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1247915.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存