gpt4 book ai didi

c++ - 依赖模板名称和 C++20 ADL

转载 作者:行者123 更新时间:2023-12-03 10:05:18 33 4
gpt4 key购买 nike

考虑以下示例:

namespace N {
template<class>
struct C { };

template<int, class T>
void foo(C<T>);
}

template<class T>
void bar(N::C<T> c) {
foo<0>(c);
}

int main() {
N::C<void> c;
bar(c);
}
GCC 和 Clang 都无法在 C++17 标准下编译此代码(使用 -Werror ),因为(根据我的理解)在 C++17 ADL 中当显式模板参数时不起作用 <...>存在(除非已将名称建立为模板名称),因此 foo是未找到的非依赖名称。
在 C++20 中,ADL 规则发生了变化,显式模板参数不会阻止 ADL。现在看来 foo成为应该可以通过 ADL 解析的依赖名称。但是,GCC 和 Clang 对这段代码的有效性有不同的看法。 CLang 编译它没有错误,但 GCC (10.2, -std=c++2a) 提示:

error: 'foo' was not declared in this scope; did you mean 'N::foo'?


在 C++17 模式下,Clang 产生以下警告:

warning: use of function template name with no prior declaration in function call with explicit template arguments is a C++20 extension


Demo .
我有三个相关的问题:
  • 哪个编译器是正确的,为什么?
  • 在 C++17 中,是 foofoo<0>(c)被视为从属名称?
  • 在 C++20 中,是 foofoo<0>(c)被视为从属名称?
  • 最佳答案

    这是 P0846 ,这是一个 C++20 特性。看来 gcc 还没有实现这一点。
    这不是依赖名称的问题,而是编译器是否知道 foo 的问题。指模板与否,foo< 也是如此做比较还是开始做模板参数。
    在 C++17 中,编译器必须已经知道 foo是一个模板名称(您可以通过添加 using N::foo; 来完成)以执行 ADL,在 C++20 中这不再正确 - 现在的规则是,如果不合格的查找找到模板或什么都没有,我们也会考虑它成为模板。
    foo的依赖没有因为这篇论文而改变。在 foo<0>(c); , foo仍然是一个从属名称。 [temp.dep]中的规则从 C++17 是:

    In an expression of the form:

    postfix-expression ( expression-listopt )

    where the postfix-expression is an unqualified-id, the unqualified-id denotes a dependent name if

    • any of the expressions in the expression-list is a pack expansion,
    • any of the expressions or braced-init-lists in the expression-list is type-dependent, or
    • the unqualified-id is a template-id in which any of the template arguments depends on a template parameter.

    第二个要点在这里适用 - c是类型相关的。 C++20 的措辞是相同的。这里的问题不在于 foo不依赖于 C++17。只是规则是当我们 foo< ,我们不知道 foo是一个模板,所以它被认为是小于运算符,然后失败。

    关于c++ - 依赖模板名称和 C++20 ADL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65225172/

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