c++ - Constexpr is not allowed in declaration of friend template specialization? -


i'm porting c++14-constexpr codebase clang latest g++-5.1. consider following reduced code snippet of home-grown bitset class has been compiling correctly since halcyon days of clang 3.3 (almost 2 years now!)

#include <cstddef>  template<std::size_t> class bitset;  template<std::size_t n> constexpr bool operator==(const bitset<n>& lhs, const bitset<n>& rhs) noexcept;  template<std::size_t n> class bitset {     friend constexpr bool operator== <>(const bitset<n>&, const bitset<n>&) noexcept;     //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <-- error piece };  template<std::size_t n> constexpr bool operator==(const bitset<n>& /* lhs */, const bitset<n>& /* rhs */) noexcept {     return true; }  int main() {} 

live example on wandbox. however, g++-5.1 , current trunk release give error:

'constexpr' not allowed in declaration of friend template specialization

question: known g++ bug or clang not conforming latest standard?

note: above uses c++11 style constexpr features, since there no modifications taking place inside operator==, seems weird interference between templates, friends , constexpr.

update: filed bug 65977 on bugzilla.

gcc wrong here.

all references n4431, latest c++ wd.

[tl;dr: there's difference between function being inline (or more precisely, being inline function, defined in 7.1.2/2) , being declared inline specifier. constexpr specifier makes function inline, isn't inline specifier.]

specifiers described in subclause 7.1 of c++ standard, , element of grammar. therefore, whenever standard talks foo specifier appearing somewhere, means specifier literally appeared within (parse tree of the) source code. inline specifier function-specifier, described in subclause 7.1.2, , effect make function inline function. (7.1.2)/2:

a function declaration (8.3.5, 9.3, 11.3) inline specifier declares inline function.

there 2 other ways declare inline function, without using inline specifier. 1 described in (7.1.2)/3:

a function defined within class definition inline function.

the other described in (7.1.5)/1:

constexpr functions , constexpr constructors implicitly inline (7.1.2).

neither of these says behavior if inline specifier present, merely function inline function.

so why rule exist?

there's simpler form of rule in (7.1.2)/3:

if inline specifier used in friend declaration, declaration shall definition or function shall have been declared inline.

the purpose of allow friend declarations ignored in cases -- not permitted add "new information" befriended entity, except in special case defining friend function. (this in turn allows implementation delay parsing class definition until it's "needed".) see, in (8.3.6)/4:

if friend declaration specifies default argument expression, declaration shall definition , shall declaration of function or function template in translation unit.

and same applies declaration of friend specialization of function template: if add information, implementations not delay parsing class definition.

now, note rationale not apply constexpr: if constexpr specifier appears on declaration of function, must appear on every declaration, per (7.1.5)/1. since there no "new information" here, there no need restriction.


Comments

Popular posts from this blog

jquery - How do you format the date used in the popover widget title of FullCalendar? -

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -