It comes as a huge disappointment that such a constraint exists and has not been relaxed in C++11 (there may be good reason but I cannot imagine why). I feel like it defeats the whole concept of class hierarchies.
Anyhow, here's one workaround I have found. I have included another function g
that is non-static to illustrate the differences, because this case is my main interest.
template <typename Y>
struct X
{
template <typename> static bool f() { return true; }
template <typename> bool g() { return true; }
template <int I>
static bool f() { return Y::template _f <I>(); }
template <int I>
bool g()
{
return static_cast <Y&>(*this).template _g <I>();
}
};
class Y : public X <Y>
{
friend class X <Y>;
template <int> static bool _f() { return false; }
template <int> bool _g() { return false; }
};
int main()
{
Y y;
std::cout << Y::f <void>() << " " << Y::f <0>() << std::endl;
std::cout << y. g <void>() << " " << y. g <0>() << std::endl;
}
So all overloading takes place in base class X
, which implements static polymorphism by taking Y
as a template argument (fortunately, this was already the case in my project so I do not change the design).
The actual Y
's implementations are in private functions _f
, _g
. This design is good when there are many derived classes like Y
with only one overload in each, and a single base class X
with multiple other overloads. In this case, massive code duplication is avoided. Again, this is the case in my project.
X
does not need to know the return value of these functions. Unfortunately, it does need to know the return type: I have tried e.g. auto g() -> decltype(...)
and again this decltype
only works in gcc. Enabling c++1y one only writes auto g()
without the trailing return type specification, thus avoiding the problem with decltype
. However, clang's support for "return type deduction for normal functions" (N3638) is only available in current SVN version.
Until auto g()
becomes mainstream (and standard), one has to compute the return type of Y
's methods by hand, which may be painful especially if there are lots of Y
s.
It still looks like a mess to me, but at least not a complete one.
return 0;
by the Standard if programmer omits a return statement frommain()
. – Barocchioint main()
orint main(int, char**)
orint main(int, char *[])
. All three are legal in C++. – Barocchiomain
, where the problem actually lies. – Melaniemelanint._()
(access element, if single),t._<3>
(element 3),t._<sz <3,5,2> >()
(indirect tuple view referring to elements 3,5,2 of underlying tuplet
) and so on. The method in question is_()
and some class hierarchy is definitely needed if the code is to be elegant and maintainable. – Melaniemelanin