我试图从http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector应用该技术来检查某个类型是否具有静态constexpr成员。
以下是我的尝试:
#include <stddef.h>
#include <stdint.h>
#include <iostream>
struct Foo {
static constexpr uint32_t magic = 100;
};
struct Bar {
static constexpr uint32_t bla = 100;
};
template <class T>
class HasMember_magic {
private:
using Yes = char[2];
using No = char[1];
struct Fallback {
static constexpr uint32_t magic = 0;
};
struct Derived : T, Fallback {};
template <class U>
static No& test(decltype(U::magic)*);
template <typename U>
static Yes& test(U*);
public:
static constexpr bool RESULT =
sizeof(test<Derived>(nullptr)) == sizeof(Yes);
};
int main(int argc, char* argv[]) {
std::cout << HasMember_magic<Foo>::RESULT << std::endl;
std::cout << HasMember_magic<Bar>::RESULT << std::endl;
return 0;
}
它适用于gcc:
$ g++ -std=c++11 test.cxx
$ ./a.out
1
0
但是clang抱怨道:
$ clang++ -std=c++11 test.cxx
test.cxx:32:24: error: call to 'test' is ambiguous
sizeof(test<Derived>(nullptr)) == sizeof(Yes);
^~~~~~~~~~~~~
test.cxx:37:22: note: in instantiation of template class 'HasMember_magic<Bar>' requested here
std::cout << HasMember_magic<Bar>::RESULT << std::endl;
^
test.cxx:25:20: note: candidate function [with U = HasMember_magic<Bar>::Derived]
static No& test(decltype(U::magic)*);
^
test.cxx:28:21: note: candidate function [with U = HasMember_magic<Bar>::Derived]
static Yes& test(U*);
^
1 error generated.
$ clang++ --version
clang version 3.4 (tags/RELEASE_34/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
$
获取static constexpr
地址的概念对我来说听起来不合适,所以我不会因为看到问题而感到沮丧。
那么,这样做的正确方法是什么?解决方案必须在gcc和clang中都有效。