c++ - std::void_t 和嵌套非类型成员

标签 c++ templates c++17 template-meta-programming sfinae

我有以下代码,但出现意外结果(第二个 static_assert 失败):

#include <type_traits>

template <typename T, typename = void>
struct is_bananas : std::false_type {};
template <typename T>
struct is_bananas<T, std::void_t<typename T::config::num_items>>
    : std::true_type {};

struct Config{
    static constexpr int num_items=42;
};

struct Bananas{
    using config = Config;
};

static_assert(is_bananas<int>::value == false);
static_assert(is_bananas<Bananas>::value == true);

当我使用 T::config 而不是 T::config::num_items 时,代码按预期工作。

如果我在 num_items 周围使用 decltype 那么它就可以工作。

我是否正确地假设 void_t 仅适用于类型?

有更好的方法来做我想做的事吗?
如果有人对此感到困惑(并认为:只需抛出一个 decltype) - 我发现当存在长名称和深度嵌套时,在实际代码中很难阅读 decltype 所以如果有是使用 void_t 或我想知道的任何其他模板代码来执行此操作的更好方法。

最佳答案

Is there a nicer way to do what I want?

好与好都是主观的。

通过示例,我发现您的 decltype() 解决方案非常好。

无论如何...一个可能的替代方案是定义与值类型一起使用的 std::void_t 的替代品

有点像

template <auto...>
using value_void_t = void;

并写

template <typename T>
struct is_bananas<T, value_void_t<T::config::num_items>>
   : std::true_type {};

关于c++ - std::void_t 和嵌套非类型成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52066493/

相关文章:

c++ - 用于创建方法的可变参数模板的模板特化

C++17 文件系统调用产生段错误

c++ - `std::isfinite()` 的编译时优化应用于整数类型

c++ - 如何获得知道其他两个的 3d vector 的剩余轴?

c++ - 为什么 C++20 不支持 "void f(Concept const auto&)"?

javascript - 在 ng-repeat 循环期间或循环后更改属性?

C++ 模板特化 - 将其他整数类型委托(delegate)给 uint64_t

c++ - 递归可变参数模板的基本案例特化

c++ - 在不修改 .h 文件的情况下处理宏重新定义 ... C/C++ 语言

c++ - 如何在 QImage 中显示此数据缓冲区