gpt4 book ai didi

c++ - 检查接受 T 参数的非成员函数是否存在

转载 作者:IT老高 更新时间:2023-10-28 22:41:36 26 4
gpt4 key购买 nike

我想检查是否存在接受 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 中是否存在错误,或者代码位于某些“实现定义”区域中,我不能假设它在所有平台上都会有相同的行为?

最佳答案

编译器之间的差异是由void_t的定义引起的: Is there a compiler bug exposed by my implementation of an is_complete type trait?简而言之,该标准不清楚别名模板特化中未使用的参数是否会导致替换失败或被忽略。分辨率为CWG issue 1558阐明问题中 void_t 的较短定义应该有效。

使用

解决了这个问题
template<typename... Ts>
struct make_void { typedef void type;};

template<typename... Ts>
using void_t = typename make_void<Ts...>::type;

both compilers produce 10 .

§14.6.4.2 [temp.dep.candidate]:

For a function call that depends on a template parameter, the candidate functions are found using the usual lookup rules (3.4.1, 3.4.2, 3.4.3) except that:

  • For the part of the lookup using unqualified name lookup (3.4.1) or qualified name lookup (3.4.3), only function declarations from the template definition context are found.
  • For the part of the lookup using associated namespaces (3.4.2), only function declarations found in either the template definition context or the template instantiation context are found.

If the function name is an unqualified-id and the call would be ill-formed or would find a better match had the lookup within the associated namespaces considered all the function declarations with external linkage introduced in those namespaces in all translation units, not just considering those declarations found in the template definition and template instantiation contexts, then the program has undefined behavior.

Serialize 的非限定查找是在模板定义上下文中执行的,不会找到 Serialize(int &),并且对于 int& 类型的参数没有 ADL ,所以 10 是正确的输出。

关于c++ - 检查接受 T 参数的非成员函数是否存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25775874/

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