gpt4 book ai didi

c++ - 对于具有附加(非推导)模板参数的函数,ADL 失败(或未完成?)

转载 作者:可可西里 更新时间:2023-11-01 16:38:01 24 4
gpt4 key购买 nike

namespace N {
class C {};

template<typename X>
char const * found(X && x) {
return "found";
}

template<typename, typename X>
char const * notfound(X && x) {
return "not found";
}
}

这定义了一个命名空间 N上课 C和两个功能模板。 found有一个模板参数,可以从函数参数中推导出来。 notfound有一个无法推导的附加模板参数。

给定以下测试代码(on ideone):

#include <iostream>
int main() {
N::C object;
std::cout
<< found(object) << std::endl
<< notfound<bool>(object) << std::endl // ERROR
<< notfound<bool, N::C>(object) << std::endl; // ERROR
}

我假设 argument dependent lookup会同时找到 foundnotfound通过参数类型 N 的最内层封闭命名空间(即 N::C ) .

但是:

prog.cpp: In function ‘int main()’:
prog.cpp:21:6: error: ‘notfound’ was not declared in this scope
<< notfound<bool>(object) << std::endl
^~~~~~~~
prog.cpp:21:6: note: suggested alternative:
prog.cpp:12:15: note: ‘N::notfound’
char const * notfound(X && x) {
^~~~~~~~

(注释掉 notfound<bool, N::C>(object) 调用后 notfound<bool>(object) 的相同错误)

为什么是notfound没有通过 ADL 找到?


背景:我正在实现 get一些包装类的函数,总的来说与 std::get(std::tuple) 比较相似.包装类,作为一个实现细节,存在于某个命名空间 lib::aspect::part::impl 中。 .我不希望图书馆的用户指定 using lib::aspect::part::impl::get出于显而易见的原因。

最佳答案

因为对带有显式指定模板参数的函数模板的函数调用要求模板的名称必须通过普通查找找到;直到那个ADL踢不进去。

来自标准:$17.8.1/8 Explicit template argument specification [temp.arg.explicit]

(强调我的)

[ Note: For simple function names, argument dependent lookup applies even when the function name is not visible within the scope of the call. This is because the call still has the syntactic form of a function call ([basic.lookup.unqual]). But when a function template with explicit template arguments is used, the call does not have the correct syntactic form unless there is a function template with that name visible at the point of the call. If no such name is visible, the call is not syntactically well-formed and argument-dependent lookup does not apply. If some such name is visible, argument dependent lookup applies and additional function templates may be found in other namespaces. [ Example:

namespace A {
struct B { };
template<int X> void f(B);
}
namespace C {
template<class T> void f(T t);
}
void g(A::B b) {
f<3>(b); // ill-formed: not a function call
A::f<3>(b); // well-formed
C::f<3>(b); // ill-formed; argument dependent lookup applies only to unqualified names
using C::f;
f<3>(b); // well-formed because C​::​f is visible; then A​::​f is found by argument dependent lookup
}

— end example ] — end note ]

最后一句给出了一个可能的解决方法;您可以在任何地方添加函数模板的声明,以使名称可见以便被调用。例如

template<typename>
void notfound();

int main() {
N::C object;
std::cout
<< found(object) << std::endl
<< notfound<bool>(object) << std::endl
<< notfound<bool, N::C&>(object) << std::endl; // btw the 2nd template argument should be N::C&
}

LIVE

关于c++ - 对于具有附加(非推导)模板参数的函数,ADL 失败(或未完成?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44490086/

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