I was playing around with constexpr counters in C++ (based on this), but there's a warning emitted by GCC that I can't get rid of. Below is a fairly minimal source demonstrating the problem. Clang emits no warning, GCC emits two (see below), one I can get rid of easily, but I didn't clutter the code with the workaround, the other baffles me. Both programs behave the same, correctly, as far as I understand.
All of the search results for the error message deal with people not doing inline functions right and other non-related issues. I've searched. I've tried pragmas, but since gcc doesn't seem to connect the warning to a warning option (e.g. -Wnon-template-friend), I can't even do that.
How can I get rid of that warning?
The warning I know how to get rid of, in multiple ways even.
question.cpp:4:32: warning: friend declaration ‘constexpr int fn(tag)’ declares a non-template function [-Wnon-template-friend] friend constexpr int fn(tag); ^ question.cpp:4:32: note: (if this is not what you intended, make sure the function template has already been declared and add after the function name here)This warnig I can't get rid of
question.cpp:4:23: warning: inline function ‘constexpr int fn(tag)’ used but never defined [enabled by default] friend constexpr int fn(tag); ^ question.cpp:4:23: warning: inline function ‘constexpr int fn(tag)’ used but never defined [enabled by default] question.cpp:4:23: warning: inline function ‘constexpr int fn(tag)’ used but never defined [enabled by default]
#include <stdio.h>
template <int N> struct tag {
friend constexpr int fn(tag<N>);
};
template <int N>
struct setter {
static constexpr int v=N;
friend constexpr int fn(tag<N>) { return v; }
};
template <int N, int Z=fn(tag<N+0>{})>
static constexpr bool is_set(int ,tag<N>) {
return true;
}
template <int N>
static constexpr bool is_set(float,tag<N>) {
return false;
}
template<int N>
static constexpr int set(int Q = setter<N+0>::v) {
return fn(tag<N>{});
}
template<int N,bool B=is_set(1,tag<N+0>{})>
static constexpr bool is_set() {return B;}
int main() {
set<1>();
printf ("%d %d %d %d\n",is_set<0>(),is_set<1>(),is_set<2>(),is_set<3>());
}
Aucun commentaire:
Enregistrer un commentaire