gpt4 book ai didi

c++ - CTAD、initializer_list、非显式构造函数和函数调用

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:42:21 24 4
gpt4 key购买 nike

基本上,我想要的是 multi_types std::initializer_list

template<typename ...As>
struct Foo {
Foo(As...){}
};

template<typename ...As>
void f(Foo<As...>) {}

int main() {
f(Foo{5, 3.f}); // 1) compile
f({}); // 2) compile
f({5, 3}); // 3) error
f({5, 3.8}); // 4) error
return 0;
}

我确实理解第一个示例编译的原因。但是,我不明白为什么第二个编译但其他的不编译。对我来说,如果第三个和第四个不编译,第二个也不应该编译。有没有办法使第三次和第四次编译?

最佳答案

However, I do not understand why the second compiles but the others don't [compile].

示例 3 和 4 无法编译,因为推导的模板参数与您期望的不同。

当您编写对函数模板的调用 ( f({5, 3})) 时 template<typename ...As> void f(Foo<As...>) ,编译器需要推断出任何缺失的模板参数(...As)。这些缺失的模板参数首先通过比较函数参数 ({5, 3}) 和函数参数 (Foo<As...>) 推导出来。如果函数参数是初始化列表 ( {5, 3} ) [1],跳过函数参数的模板参数推导 ( Foo<As...> ):

N4659 [temp.deduct.call] 17.8.2.1(1):

[...] an initializer list argument causes the parameter to be considered a non-deduced context (17.8.2.5).

N4659 [temp.deduct.type] 17.8.2.5(5.6):

[Non-deduced contexts include a] function parameter for which the associated argument is an initializer list (11.6.4) [...]

因为尾随的模板参数包 ( As... ) 没有被任何函数参数推导出来,它被推导出为空:

N4659 [temp.arg.explicit] 17.8.1(3):

A trailing template parameter pack (17.5.3) not otherwise deduced will be deduced to an empty sequence of template arguments.

对于 f({5, 3}) ,编译器推断模板参数是 <> (空),因此被调用的特化是void f(Foo<>) 。重要提示:无论初始化列表中有什么,都会选择此特化。这解释了编译器给出的诊断:

Clang:
error: no matching function for call to 'f'
note: candidate function [with As = <>] not viable: cannot convert initializer list argument to 'Foo<>'

GCC:
error: could not convert '{5, 3}' from '' to 'Foo<>'

MSVC:
error C2664: 'void f<>(Foo<>)': cannot convert argument 1 from 'initializer list' to 'Foo<>'
note: No constructor could take the source type, or constructor overload resolution was ambiguous

在函数调用中,函数参数使用函数参数中的复制初始化 进行初始化。以下语句使用与您的示例初始化 f 的参数相同的规则初始化变量:

Foo<> x = {};        // Example 2
Foo<> x = {5, 3}; // Example 3
Foo<> x = {5, 3.8}; // Example 4

[1] 简而言之,如果函数参数既不是 std::initializer_list<T>也不T[n]

关于c++ - CTAD、initializer_list、非显式构造函数和函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54824308/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com