gpt4 book ai didi

c++ - 模板元编程 : checking for existence of a function defined later

转载 作者:太空狗 更新时间:2023-10-29 21:13:49 24 4
gpt4 key购买 nike

我正在解决一个经典问题:检查某个命名空间中是否存在自由函数。它被讨论,例如,here .

但是,有一个细微的差别:函数的定义可能比检查器类出现。这是一个例子。

struct Yes {};
struct No {};
struct YesButLater {};

void f(Yes) {}

template<typename T, typename Enable = void>
struct HasF : public std::false_type {};

template<typename T>
struct HasF<T, decltype(void( ::f(T()) ))> : public std::true_type {};

void f(YesButLater) {}

int main() {
cout << HasF<Yes>::value << endl; // 1
cout << HasF<No>::value << endl; // 0
cout << HasF<YesButLater>::value << endl; // 0, expected 1
}

f(YesButLater) 的声明晚于 HasF 辅助类,而且,尽管我在定义了 f(YesButLater) 之后实例化了模板,助手没有注意到它。

那么,问题一来了:我该如何处理?

现在再举一个更奇怪的例子。

template<typename T>
struct HasF<T, decltype(void( f(T()) ))> : public std::true_type {};

void f(YesButLater) {}
void f(std::string) {}

int main() {
cout << HasF<YesButLater>::value << endl; // 1 (but what's the difference?)
cout << HasF<std::string>::value << endl; // 0, expected 1
}

请注意,我从 decltype(...) 表达式中删除了 ::。现在由于某些原因 f(YesButLater) HasF 注意到,但是 f(std::string) 仍然仍然晦涩难懂。

问题 2:为什么我们在这个例子中观察到 ::f(T())f(T()) 的不同行为?此外,YesButLaterstd::string 有什么区别?

我认为命名空间查找有一些技巧,但我无法找到它。

最佳答案

看来我已经弄明白是怎么回事了。

当我编写 ::f(...) 时,正在使用 限定名称查找 搜索名称 f。这种查找只会遇到声明在调用点之前可用的名称。现在很清楚为什么第一个版本找不到 f(YesButLater):它的声明发生在后面。

当我编写 f(...) 时,发生了非限定名称查找。同样,它找不到在调用点之前声明的任何名称。这里 argument dependent lookup 出现了。它在T 所属的整个 命名空间中搜索f(T)。在 f(YesButLater) 的情况下,这个命名空间是全局的,因此可以找到该函数。如果是 f(std::string),ADL 会尝试搜索 std::f(std::string),当然会失败。

这里有两个例子来说明这个问题。

namespace foo {
class C {};
}

template<typename T>
void call() {
f(T());
}

namespace foo {
void f(C) {}
}

int main() {
call<foo::C>();
}

这里 f(T()) 正在使用 ADL 搜索并找到,尽管它的声明在 call() 之后。如果我们修改 call() 函数...

template<typename T>
void call() {
foo::f(T());
}

这会导致编译错误,因为 foo::f(T) 执行合格的查找并且找不到所需的函数,因为此时没有可用的声明。

关于c++ - 模板元编程 : checking for existence of a function defined later,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42833134/

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