我试图想出一个hack来测试是否std::isnan在预处理器中没有特殊的外壳编译器来定义,并提出了以下内容,我期望它能正常工作.
#include <cmath>
#include <type_traits>
namespace detail {
using namespace std;
struct dummy {};
void isnan(dummy);
//bool isnan(float); // Just adding this declaration makes it work!
template <typename T>
struct is_isnan_available {
template <typename T1>
static decltype(isnan(T1())) test(int);
template <typename>
static void test(...);
enum { value = !std::is_void<decltype(test<T>(0))>::value };
};
}
int main() {
return detail::is_isnan_available<float>::value;
}
Run Code Online (Sandbox Code Playgroud)
事实证明它没有检测到它.我知道肯定std::isnan是在ideone上定义的,因为我手动测试了.
当我取消注释上面标记的行时,它可以工作.
我在这里错过了什么?什么解释了这种行为?
问题是,using指令不会向当前命名空间添加成员,因此std::成员仍然可以被此命名空间中的声明隐藏.
using std::isnan相反,它会像导入的命名空间的成员被添加到包含use-location和导入的命名空间的命名空间一样.using声明是命名空间中的普通声明,因此可以使用后面的声明参与重载解析.
但是,正如评论中指出的那样,如果函数不存在,则会产生错误.要解决这个问题,您需要将其从detail::命名空间中删除.这应该工作,因为导入的定义将与dummy重载处于同一级别.您可以将重载带到全局命名空间,也可以创建辅助命名空间(在全局命名空间中)并导入两者.
| 归档时间: |
|
| 查看次数: |
465 次 |
| 最近记录: |