Now, I'm not sure what the standard says;
This case has in fact been clarified with an example in the upcoming C++17
[temp.inst]/2 The implicit instantiation of a class template specialization ... [snip] ... for the purpose of determining whether an instantiated redeclaration of a member is valid according to 3.2 [basic.def.odr] and 9.2 [class.mem], a declaration that corresponds to a definition in the template is considered to be a definition. [ Example:
... [snip (another example)] ...
template<typename T> struct Friendly {
template<typename U> friend int f(U) { return sizeof(T); }
};
Friendly<char> fc;
Friendly<float> ff; // ill-formed: produces second definition of f(U)
— end example ]
Admittedly as you point out, the example of the standard does produce a different definition for each instantiation, but that is not necessary for the example to be ill-formed according to that rule.
So why can't it apply the "oh, all inline copies of the same definition of a function are the same" rule?
This question seems to apply to the a much simpler situation as well:
inline void foo(){}
inline void foo(){}
Surely a compiler can see that the definitions are identical, just as much as a compiler can see that the definition of your ::bar
depends not on the template argument of Foo
.
Yet, odr says that the re-definition is ill-formed. This is true for definitions outside a class template, as well as definitions that are caused by instantiation of a class template.
Perhaps odr could be relaxed for the case that you demonstrate, but that would require complicating the standard with a special case rule, and complicate the compilers that then would have to analyse whether template arguments are used within the definition, so such relaxation certainly isn't without compromise.
inline
. Try addinginline
to it, and see if it works? – Anabranchinline
since it's in the class definiton (IIANM); addinginline
doesn't help. – Christmanninline void f() {} inline void f() {}
? – Clemenciaclemency