[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1009081: g++-11: friend statement not used for template specialization



  Hi,

  More strange: by adding an unused static method, the behavior
of the previous templates change.

$ cat toto6.cpp
#include <iostream>

struct X {
  template <class T, class U = void> struct check_is_map {
      static constexpr bool value = false;
  };

  template <class T>
  struct check_is_map<T, typename T::is_map> {
      static constexpr bool value = true;
  };

  template <class T> struct check_is_map2 {
    static constexpr bool value = check_is_map<T>::value;
  };

  static void func();
};

template <class T, class U = void> struct check_is_map {
    static constexpr bool value = false;
};

template <class T>
struct check_is_map<T, typename T::is_map> {
    static constexpr bool value = true;
};

struct Config {
    using is_map=void;
};

struct ConfigBis {
  private:
    template <typename T1, typename U1>
    friend struct check_is_map;
    friend struct X;
    using is_map=void;
};

#ifdef FOO
void X::func() {
	std::cerr << "* Through method" << std::endl;
	std::cerr << "X::VALUE (public): "
            << X::check_is_map<Config>::value
                  << std::endl;
	std::cerr << "X::VALUE (private+friend): "
            << X::check_is_map<ConfigBis>::value
                  << std::endl;
	std::cerr << "** By proxy template" << std::endl;
	std::cerr << "X::Proxy::VALUE (public): "
            << X::check_is_map2<Config>::value
                  << std::endl;
	std::cerr << "X::Proxy::VALUE (private+friend): "
            << X::check_is_map2<ConfigBis>::value
                  << std::endl;
}
#endif

int main()
{
	std::cerr << "* From main" << std::endl;
	std::cerr << "VALUE (public): "
            << check_is_map<Config>::value
                  << std::endl;
	std::cerr << "VALUE (private+friend): "
            << check_is_map<ConfigBis>::value
                  << std::endl;
	std::cerr << "X::VALUE (public): "
            << X::check_is_map<Config>::value
                  << std::endl;
	std::cerr << "X::VALUE (private+friend): "
            << X::check_is_map<ConfigBis>::value
                  << std::endl;
	std::cerr << "** By proxy template" << std::endl;
	std::cerr << "X::Proxy::VALUE (public): "
            << X::check_is_map2<Config>::value
                  << std::endl;
	std::cerr << "X::Proxy::VALUE (private+friend): "
            << X::check_is_map2<ConfigBis>::value
                  << std::endl;
}
$ g++ -std=gnu++17 -Wall -Wextra toto6.cpp
$ ./a.out
* From main
VALUE (public): 1
VALUE (private+friend): 0
X::VALUE (public): 1
X::VALUE (private+friend): 0
** By proxy template
X::Proxy::VALUE (public): 1
X::Proxy::VALUE (private+friend): 0
$ g++ -std=gnu++17 -Wall -Wextra toto6.cpp -DFOO
$ ./a.out
* From main
VALUE (public): 1
VALUE (private+friend): 0
X::VALUE (public): 1
X::VALUE (private+friend): 1
** By proxy template
X::Proxy::VALUE (public): 1
X::Proxy::VALUE (private+friend): 1

  Regards,
    Vincent


Reply to: