具有模板类型的C ++ 20指定的初始化程序 [英] C++20 designated initializers with templated types

查看:95
本文介绍了具有模板类型的C ++ 20指定的初始化程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

指定的初始化程序(C ++ 20)应该如何与CTAD一起使用?

How are designated initializers (C++20) supposed to work with CTAD?

此代码在gcc9.2中可以正常工作,但在clang8中失败

This code works fine in gcc9.2, but fails with clang8

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{.first = 20, .second = 20.f};
    static_assert( std::is_same_v<decltype(x.first), int> );
    static_assert( std::is_same_v<decltype(x.second), float> );
}

这应该是有效的吗?

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

推荐答案

是的,这应该是有效的。

Yes, this is supposed to be valid.

CTAD的工作方式是我们对一组综合的构造函数执行重载解析,以弄清类模板参数是什么。从C ++ 17开始,该综合的构造函数集仅基于主模板的构造函数和推论指南(我正在更改模板参数名称,因为我发现它们非常混乱):

The way CTAD works is we perform overload resolution over a synthesized set of constructors to figure out what the class template parameters were. From C++17, that synthesized set of constructors is just based on the primary template's constructors and deduction guides (I'm changing the template parameter names because I find them very confusing):

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

C ++ 20添加了一个新的总扣除额候选项。对于 initializer-list designated-initializer-list 中的每个元素,我们选择集合中的相应元素并将其类型用作新的候选对象。对于

C++20 adds a new aggregate deduction candidate. For each element of either the initializer-list or designated-initializer-list, we pick the corresponding element of the aggregate and use its type as the new candidate. For

my_pair x{.first = 20, .second = 20.f};

first 的类型为 T second 的类型为 U ,因此:

The type of first is T and the type of second is U, hence:

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

现在,我将这四个候选函数写为函数(因为我发现将它们视为函数更容易),但用语将它们定义为假设类类型的构造函数。因此,当我们使用 {。first = 20,.second = 20.f} 执行重载解析时,如果您斜视它是可行的。

Now, I wrote these four candidates as functions (because I find it easier to think of them as functions) but the wording defines them as constructors of a hypothetical class type. So when we perform overload resolution using {.first = 20, .second = 20.f}, if you squint it kind of works.

最后一个候选者是最佳候选者(只有汇总扣除候选者和扣除指南才是可行的,汇总扣除候选者更专​​业),所以我们最后得到 my_pair< int,float>

The last 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{.first = 20, .second = 20.f};

当然可以。

这篇关于具有模板类型的C ++ 20指定的初始化程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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