#include <cstddef>
template<std::size_t>
class bitset;
template<std::size_t N>
constexpr bool operator==(const bitset<N>&, const bitset<N>&) noexcept;
template<std::size_t N>
class bitset
{
friend constexpr bool operator== <>(const bitset<N>&, const bitset<N>&) noexcept;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <-- error from this piece
};
template<std::size_t N>
constexpr bool operator==(const bitset<N>&, const bitset<N>&) noexcept
{
return true;
}
int main() {}
Clang compiles this code just fine (in c++11 mode, and has been since at least clang 3.3). However, g++ (4.8 nor 5.1) does not (it even has a dedicated unit test against it). Its error message
'constexpr' is not allowed in declaration of friend template specialization
seems to be a conflict between [dcl.constexpr]/2 (constexpr functions are implicitly inline) and [temp.friend]/9 (the inline specifier shall not be used in the declaration of a specialization of a function template). It would be rather annoying if completely idiomatic use of operator overloading is not possible in combination with the constexpr keyword. Furthermore, I find it hard to believe that an implicit inline is equivalent to the inline specifier (the implication should only run from the latter to the former, not the other way around)