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: