gpt4 book ai didi

c++ - 使用 void_t 进行成员检测

转载 作者:可可西里 更新时间:2023-11-01 18:26:18 31 4
gpt4 key购买 nike

对于 C++14 中的成员检测,我使用了基于示例 here 的代码, 但它似乎不起作用。

一个完整的例子:

#include <string>

template <typename...>
using void_t = void;

template <typename, typename = void> class HasMember_substr : public std::false_type {};
template <typename T> class HasMember_substr<T, void_t<typename T::substr>> : public std::true_type {};

template <typename, typename = void> class HasMember_fff : public std::false_type {};
template <typename T> class HasMember_fff<T, void_t<typename T::fff>> : public std::true_type {};

static_assert(HasMember_substr<std::string>::value, "");
static_assert(!HasMember_fff<std::string>::value, "");

int main() { return 0; }

在 OS X 上使用 clang++ --std=c++14 test.cpp 编译,编译器版本(clang++ --version):Apple LLVM 版本7.0.2 (clang-700.1.81)

第二个断言成功,但第一个失败。为什么?我也尝试过使用 decltype(T::substr) 而不是 typename T::subset,结果相同。

最佳答案

正在寻找 T::substr与查找名为 substr 的成员函数不同. gcc.godbolt.org example

您可以使用 std::declval<T>() 检查成员函数是否存在。并使用 decltype获取成员函数的返回类型。

如果成员函数存在,decltype(...)将是一个格式正确的表达式,不会触发 SFINAE - 因此 static_assert将正常工作。

#include <string>
#include <type_traits>
#include <utility>

template <typename...>
using void_t = void;

template <typename, typename = void>
class HasMember_substr : public std::false_type {};

template <typename T>
class HasMember_substr<T, void_t<
decltype(std::declval<T>().substr(1, 1))>
> : public std::true_type {};

static_assert(HasMember_substr<std::string>::value, "");

int main() { return 0; }

请注意 decltype(std::declval<T>().substr(1, 1))检查是否T有一个 substr可以用参数调用的成员 1, 1 . (这不保证是成员函数,例如,它也可以是仿函数数据成员。)


正如 AndyG 在评论中所说,另一种可能的方法是使用 decltype “验证”成员函数指针的类型。

例子:

HasMember_substr<T, void_t< decltype(&T::substr)>

请注意,如果名称 substr 这将不起作用重载了,它is not guaranteed to work with any type in the standard library .

关于c++ - 使用 void_t 进行成员检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34402126/

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