【发布时间】:2014-09-10 22:07:43
【问题描述】:
我想检查是否存在接受 T 参数类型的非成员函数。为此,我使用了由 Walter E. Brown 先生在 cppcon 提出的void_t“技巧”(同样的技巧可以毫无问题地检查成员类型或成员函数是否存在)。
#include <iostream>
#include <type_traits>
template<typename...>
using void_t = void;
void Serialize(float&)
{
}
template<typename T, typename = void>
struct has_external_serialize : std::false_type
{
};
template<typename T>
struct has_external_serialize<T, void_t<decltype(Serialize(std::declval<T&>()))>> : std::true_type
{
};
void Serialize(int&)
{
}
int main(int argc, const char * argv[])
{
std::cout<<has_external_serialize<float>::value<<has_external_serialize<int>::value;
}
此代码在使用 GCC 编译时打印 11,在使用 clang(xcode 5.1.1) 编译时打印 10。
我的问题是 - 这段代码是否正确?如果是,clang 中是否存在错误或 GCC 中是否存在错误,或者代码在某些“实现定义”区域中,我不能假设它在所有平台上都会有相同的行为?
【问题讨论】:
-
在专业化之前坚持依赖类型和
std类型。其他类型使用 ADL。那么铿锵会很高兴。我相信你所做的事情是错误的,但没有时间证明这一点 -
看起来更像是 GCC 中的一个错误(至少 4.9.0),因为它打印
11即使是struct has_external_serialize<T, void_t<decltype(SomeNonExistingFunc(std::declval<T&>()))>> : std::true_type -
@Felics:欢迎来到 CppCon! :-)
-
我无法回答你的问题,但这里有一个 g++ 也很满意的技巧:coliru.stacked-crooked.com/a/f7af49a7f53fbe4d
-
@Jamboree 谢谢!我知道还有其他方法可以解决这个问题,其中一些很好,就像你发布的那样,另一些带有一些恐怖代码:)