使用 void_t 和受保护的嵌套类的基于 SFINAE 的检测

Posted

技术标签:

【中文标题】使用 void_t 和受保护的嵌套类的基于 SFINAE 的检测【英文标题】:SFINAE-based detection using void_t and protected nest classes 【发布时间】:2018-12-24 21:36:21 【问题描述】:

我最近在 clang 和 gcc 之间遇到了一些关于 void_t 属性检测和受保护/私有类信息的不同行为。考虑如下定义的类型特征:

#include <type_traits>

template<typename T, typename = void>
constexpr const bool has_nested_type_v = false;

template<typename T>
constexpr const bool has_nested_type_v
<T, std::void_t<typename T::type>> = true;

给定具有受保护或私有嵌套type 类和一个简单程序的示例类型

#include "has_nested_type.hpp"
#include <iostream>

struct Protected 
protected:
  struct type;
;

struct Private 
private:
  struct type;
;

int main() 
  std::cout << "Protected: " 
            << (has_nested_type_v<Protected> ? "detected" : "not detected")
            << std::endl;
  std::cout << "Private: " 
            << (has_nested_type_v<Private> ? "detected" : "not detected")
            << std::endl;

clang 编译成功,但检测失败(如预期的那样)。程序、编译、输出都在wandboxhere上转载。

gcc 无法编译,发出诊断信息。此错误可以在 wandbox here 上重现。

GCC 对此程序发出以下错误。

prog.cc:16:21: error: 'struct Protected::type' is protected within this context
                 << (has_nested_type_v<Protected> ? "detected" : "not detected")
                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cc:6:14: note: declared protected here
       struct type;
              ^~~~
prog.cc:19:21: error: 'struct Private::type' is private within this context
                 << (has_nested_type_v<Private> ? "detected" : "not detected")
                     ^~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cc:11:14: note: declared private here
       struct type;
              ^~~~

我的问题是哪种行为符合标准?是否应该在此处发出 clang 错误并发出诊断信息,还是 GCC 过于急切?

【问题讨论】:

MSVC 给出的结果与 Clang、FWIW 相同(使用 VS 2017 测试)。 icc 也编译它:godbolt.org/z/xuVKjU 【参考方案1】:

这是GCC bug。它是 following meta-bug 的一部分,描述了几个与访问相关的错误。

【讨论】:

哎呀。自 2013 年以来表现出色。这真是太可惜了。

以上是关于使用 void_t 和受保护的嵌套类的基于 SFINAE 的检测的主要内容,如果未能解决你的问题,请参考以下文章

多态性和受保护的继承问题

在反应中使用 cookie 的客户端身份验证和受保护的路由

STM32加密保护工具 | STM32Trust生成SFI和SMI加密固件

在 C# 中是不是可以使用内部和受保护的成员? [复制]

关于何时使用私有域和受保护域的困惑

抽象类的 C++ 保护构造函数