我正在解决一个经典问题:检查某个命名空间中是否存在自由函数。这个问题已经被讨论过了,例如在这里。
然而,有一个小小的变化:函数的定义可能出现在检查类之后。以下是一个例子。
请注意,我从
问题2:为什么我们在这个例子中观察到
我认为这里有一些命名空间查找的技巧,但我无法理解。
然而,有一个小小的变化:函数的定义可能出现在检查类之后。以下是一个例子。
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)
后实例化模板,但辅助程序并未注意到它。
那么,问题1:我该如何解决这个问题?
现在再来一个更有趣的例子。
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())
有不同的行为?此外,YesButLater
和std::string
之间有什么区别?我认为这里有一些命名空间查找的技巧,但我无法理解。