SFINAE-based detection using void_t and protected nest classes
Asked Answered
F

1

7

I encountered some divergent behavior between clang and gcc recently regarding void_t property detection and protected/private class information. Consider a type trait defined as follows:

#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;

Given example types with protected or private nested type classes and a simple program

#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 compiles successfully with a failed detection (as expected). The program, compilation, and output are reproduced on wandbox here.

  • gcc fails to compile, issuing a diagnostic. This error can be reproduced on wandbox here.

GCC issues the following error for this program.

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{};
              ^~~~

My question is which behavior is standard conformant? Should clang error here and issue a diagnostic or is GCC being overly eager?

Foin answered 24/12, 2018 at 21:36 Comment(2)
MSVC gives the same results as Clang, FWIW (tested with VS 2017).Beshrew
icc also compiles it: godbolt.org/z/xuVKjUGadabout
N
4

This is a GCC bug. It's a part of the following meta-bug that describes several access-related bugs.

Nernst answered 24/12, 2018 at 22:15 Comment(1)
Oof. Outstanding since 2013. That's really a shame.Foin

© 2022 - 2024 — McMap. All rights reserved.