C ++ 20中的CTAD和指定的初始值设定项 [英] CTAD and designated initializers in C++20

查看:97
本文介绍了C ++ 20中的CTAD和指定的初始值设定项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此问题中,我已经对指定的初始化程序对CTAD感到困惑。 ,但我对另一个非常相似的代码段感到困惑

I have already stated confusion about CTAD with designated initializers in this question, but i have another confusion with a very similar code snippet

template <typename int_t=int, typename float_t=float>
struct my_pair {
    int_t   first;
    float_t second;
};

template<typename ... ts>
my_pair(ts...) -> my_pair<ts...>;

int main() {
    my_pair x{.second = 20.f};
    static_assert( std::is_same_v<decltype(x.first), int> ); //FAILS <- its deduced to float
    static_assert( std::is_same_v<decltype(x.second), float> );
}

似乎扣除指南导致了类型first 被推导为 float ,即使我没有明确给出。first在指定的初始值设定项中。无论关键字( .second ),推导指南显然只关心初始化程序中的顺序。推导指南应该聪明吗?还是应该有指定的推导指南?

It seems like the deduction guide causes the type of first to be deduced to float, even though i do not give an explicit .first in the designated initializer. The deduction guide apparently only cares about the order in the initializer, no matter the keyword (.second). Should the deduction guide be smart about this or should there be a "designated deduction guide"?

请参见 https://godbolt.org/z/cm6Yi7

推荐答案

请以此答案为起点。我们具有相同的初始三个候选:

See this answer as a starting point. We have the same initial three candidates:

template <class T=int, class U=float>
struct my_pair {
    T first;
    U second;
};

// default constructor
template <class T=int, class U=float>
auto __f() -> my_pair<T, U>;

// copy candidate
template <class T=int, class U=float>
auto __f(my_pair<T, U>) -> my_pair<T, U>;

// deduction guide
template <class... T>
auto __f(T...) -> my_pair<T...>;

总扣除额候选者基于实际的 initializer-list 或我们提供的是 designated-initializer-list ,而不是集合的实际基础成员。我们的 designated-initializer-list {。second = 20.f} ,因此我们的总扣除额候选者变为:

And the aggregate deduction candidate is based on the actual initializer-list or designated-initializer-list we provide, not the actual underlying members of the aggregate. Our designated-initializer-list is {.second = 20.f} so our aggregate deduction candidate becomes:

// aggregate deduction candidate
template <class T=int, class U=float>
auto __f(U) -> my_pair<T, U>;

模板参数始终来自主类模板,因此我们从那里引入默认模板参数。候选参数来自 initializer-list ,而 second 的类型为 U

The template parameters always come from the primary class template, so we bring in the default template arguments from there. The candidate arguments come from the initializer-list, and the type of second is U.

总扣除额候选者是最佳候选者(只有总扣除额候选者和扣除指南是可行的,总扣除额候选者更专​​业),因此我们得出结论。和 my_pair< int,float>

The aggregate deduction candidate is the best candidate (only the aggregate deduction candidate and the deduction guide are viable, the aggregate deduction candidate is more specialized), so we end up with my_pair<int, float>.

已完成CTAD,我们现在重新开始并有效地做

Having finished CTAD, we now start over and effectively do

my_pair<int, float> x{.second = 20.f};

哪个工作,并导致 x.first {} 初始化。

Which works, and leads to x.first being initialized from {}.

CTAD汇总仅在最近才被采用(两个月前在2019年7月的科隆会议上)。在使用该功能之前,它的格式仍然应该正确:

CTAD for aggregates was only adopted very recently (at the Cologne meeting in July 2019, two months ago). Before that feature, this would still have been well-formed:

my_pair{.second = 20.f};

为什么?我们尚无汇总扣除对象,但我们仍然有扣除指南...可行的。它使我们 my_pair< float> 。也就是说,填写 U 的默认模板参数后, my_pair< float,float>

Why? We don't yet have the aggregate deduction candidate, but we still do have the deduction guide... which is viable. It gives us my_pair<float>. Which is to say, my_pair<float, float> once you fill in the default template argument for U.

这就是为什么gcc会为您提供您所看到的行为的原因-它只是尚未为聚合实现CTAD,而是为您提供了旧的行为。

That's why gcc is giving you the behavior you see - it simply does not yet implement CTAD for aggregates, and is giving you the old behavior.

这篇关于C ++ 20中的CTAD和指定的初始值设定项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆