gpt4 book ai didi

c++ - clang 没有看到通过 typedef 引入的基类构造函数

转载 作者:行者123 更新时间:2023-12-02 01:31:41 30 4
gpt4 key购买 nike

以下代码

#include <vector>
#include <string>

template<typename T>
struct V : public std::vector<T>
{
using Impl = std::vector<T>;
using typename Impl::vector; // the constructors
};

int main()
{
std::string empty;
V<std::string> meow{42UL, empty};
}

由 GCC 8.2 编译良好(调用 size_t, string 构造函数)。然而,clang 最多 14 会拒绝它

<source>:14:20: error: no matching constructor for initialization of 'V<std::string>' (aka 'V<basic_string<char>>')
V<std::string> meow{42UL, empty};
^ ~~~~~~~~~~~~~
<source>:5:8: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided
struct V : public std::vector<T>
^
<source>:5:8: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided
<source>:5:8: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 2 were provided

就好像 V 没有构造函数:https://godbolt.org/z/M91zb6Pjr

using typename Impl::vector; 替换为 using Impl::Impl; 使 clang 接受该代码。这是怎么回事?

最佳答案

自从最近的决议 CWG issue 2070不再可能使用依赖别名来继承 using 中的构造函数声明,除非重复别名的名称。

必须使用与引用构造函数相同的标识符来命名基类(嵌套-之后的最后一个unqualified-id名称说明符),例如:

using std::vector<T>::vector;

或者利用 V 中基类的注入(inject)类名的查找:

using V::vector::vector;

或者通过使用声明符的特殊规则,别名的名称也可以重复,而不是使用注入(inject)的类名(如果它是依赖的):

using Impl::Impl;

(参见https://eel.is/c++draft/basic#class.qual-1.2https://eel.is/c++draft/namespace.udecl#1.sentence-3)

如果你写using typename Impl::vector;相反,它不是继承构造函数,而是 vector将被解释为由 vector<T> 中注入(inject)的类名命名的类型,然后作为名称 vector 导入进入类范围。

这个要求是为了避免同样的using line 有时会导致构造函数被继承,有时会导致类型名称被导入,具体取决于模板的专门化。

基本上,在解决之后你就知道using具有依赖嵌套名称说明符的声明当且仅当它以 A::A 结尾时才继承构造函数。或A::A对于某些名字A (可能还有额外的模板参数列表等)。

看来 Clang 一直都是这样实现的,尽管我认为按照问题解决之前的标准来看,这并不是真正正确的。

关于c++ - clang 没有看到通过 typedef 引入的基类构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73160006/

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