在下面的代码示例中,我们有两个类X和Y,两者都可以隐式转换为n1::Base。Base支持加法,所以我认为X也Y应该通过转换为Base. 相反,他们仅在其模板参数是时才支持它Base(即使该模板参数未在任何地方使用)。
谁能解释这是为什么吗?如果您能给我指出该标准的一部分或链接相关的 cppreference.com 文章,我会加分。
X如果和Y全部支持加法或不支持加法,这对我来说将是直观的。但我不明白为什么它们只使用适当的模板参数进行编译。如果您不确定为什么这让我感到困惑,我很乐意为您提供更多说明。我猜它与 ADL(参数相关查找)有关,但我不确定。
Godbolt 链接:https://godbolt.org/z/xe3enE9Tf
代码:
#include <iostream>
namespace n1 {
struct Base {};
int operator+(Base const&, int other) { return other; }
}
using n1::Base;
// Uncommenting this would fix the error below.
// using n1::operator+;
template <class = Base>
struct X {
Base b;
operator Base() { return b; }
};
template <class = void>
struct Y {
Base b;
operator Base() { return b; }
};
int main() {
std::cout << Base{} + 3;
std::cout << X{} + 3; // Compiles
std::cout << Y<Base>{} + 3; // Also compiles
std::cout << Y{} + 3; // Doesn't compile
std::cout << X<void>{} + 3; // Also doesn't compile
}
Run Code Online (Sandbox Code Playgroud)
立即回答我的问题感觉很愚蠢,但当我阅读更多有关 ADL 的内容后,我发现了这条线。来自 cppreference (强调我的):
\n\n\n...
\n否则,对于函数调用表达式中的每个参数,都会检查其类型以确定它将添加到查找中的关联的命名空间和类集。
\n...
\n3) 对于类型为类模板特化的参数,除了类规则之外,还会检查以下类型,并将其关联的类和命名空间添加到集合中。
\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0a)为类型模板参数提供的所有模板参数的类型(跳过非类型模板参数和跳过模板模板参数)。
\n
简而言之,模板参数的命名空间X被Y添加到关联的命名空间集中。如果参数来自n1,n1::operator+则变为可见。
| 归档时间: |
|
| 查看次数: |
44 次 |
| 最近记录: |