dimanche 6 août 2017

Conflicting mismatched tags compile with standard library but not otherwise

I was taking a look at how std::tuple_size is defined in the standard library on my system. I have a Mac OS, and the compiler version is Apple LLVM version 8.1.0 (clang-802.0.42). The standard library is found in the InstalledDir location as outputted by g++ --version

Given that the following code does not compile

#include <iostream>
#include <utility>
#include <array>
#include <type_traits>

using std::cout;
using std::endl;

template <class T>
class Something;
template <class One, class Two>
struct Something<std::pair<One, Two>>;
template <class One, class Two>
class Something<std::pair<One, Two>>
    : public std::integral_constant<int, 2> {};

int main() {
  cout << std::tuple_size<std::array<int, 2>>::value << endl;
  cout << std::tuple_size<std::tuple<int, int>>::value << endl;
  cout << std::tuple_size<std::pair<int, int>>::value << endl;
}

I saw the following code in the standard library header <array> (with the definition of tuple_size as a class following later on)

template <class T> class tuple_size;
template <size_t I, class T> class tuple_element;
template <class T1, class T2> struct tuple_size<pair<T1, T2> >;

How does this compile when used in the above code after removing the definition and declarations for Something? Shouldn't the above code raise warnings about tuple_size being defined or declared twice once as a class and another as a struct?

Aucun commentaire:

Enregistrer un commentaire