Reputation: 406
template<typename T> struct Derived: T
{
/*static*/ int foo(int x) { return T::foo(x) + 1; }
};
If T::foo(int x)
is static
then Derived<T>::foo(int x)
should also be static
. Otherwise Derived<T>::foo(int x)
should be non-static.
Is there a way to let the compiler take care of this?
Upvotes: 1
Views: 160
Reputation: 69988
Use below construct:
static_assert(std::is_same<decltype(&Derived::foo), decltype(&T::foo)>::value or
(std::is_member_function_pointer<decltype(&Derived::foo)>::value and
std::is_member_function_pointer<decltype(&T::foo)>::value),
"Derived::foo & T::foo are not having same static-ness");
I have tested quickly with my g++ and it works fine.
static
. This means that the methods signatures are
expected to be same (as implied in your example).foo
are function pointers of
their respective classes types. Here no strictness of type, but you can impose with some more meta programming. Leaving up to you.If both of above fails, then the compiler gives an error. This static_assert
can be put within class Derived
.
Notes: (1) If Derived::foo
is static
& T::foo
is not then anyways, it gives error. (2) or
& and
are official keywords of C++. If certain compilers like MSVC doesn't support then use ||
& &&
respectively.
Upvotes: 0
Reputation: 76297
No, you cannot propagate static
ness in the sense you ask. Incidentally, you could also ask the same thing about const
:
int foo(int x) { return bar(x) + 1; } // Infer that foo is const because bar is
C++ specifiers are meant to convey intent about the interface, on which users can rely even if the implementation changes:
static int foo(x); // This method does not require an object
int foo(x) const; // This method will not modify the object
In case - through templates, for example - the implementation may vary, your interface must reflect the lowest common denominator. For const
, for example, methods need to be non-const
. For static
, which is your question, you cannot declare static
.
Note that this is not a huge imposition. Even if a method is static
, you can still call it using with object semantics. So, in your case, you'll have to just use object semantics. In particular, regarding your clarification in the comments
If allocator is static then container doesn't need to hold it's pointer. So decorators must preserve staticness.
note that decorators can also not preserve static
ness, because containers can hold pointers in any case, and call them via object notation, regardless of their const
ness.
Upvotes: 1