Propagate method staticness to derived class - c++

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?

No, you cannot propagate staticness 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 staticness, because containers can hold pointers in any case, and call them via object notation, regardless of their constness.

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.
What it does
Takes address of both the methods and if they are comparable then
they must be static. This means that the methods signatures are
expected to be same (as implied in your example).
If (1) fails then check if both the 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.

Related

Why can't operator () of stateless functor be static?

Why is operator () of stateless functor not allowed to be static? Stateless lambda objects are convertible to pointers to free functions having the same signature as their operator ().
Stephan T. Lavavej on p. 6 points out that conversion to a function pointer is just an operator FunctionPointer() (cite). But I can't obtain a corresponding pointer to operator () as to non-member function. For functor struct F { void operator () () {} } it seems to be impossible to convert &F::operator () to instance of type using P = void (*)();.
Code:
struct L
{
static
void operator () () const {}
operator auto () const
{
return &L::operator ();
}
};
The error is
overloaded 'operator()' cannot be a static member function
but operator () is not overloaded.
Per standard 13.5/6,
An operator function shall either be a non-static member function or be a non-member function and have
at least one parameter whose type is a class, a reference to a class, an enumeration, or a reference to an
enumeration.
Additionally, in 13.5.4 it is stated that
operator()
shall be a non-static member function with an arbitrary number of parameters. It can have
default arguments. It implements the function call syntax
postfix-expression
(
expression-list
opt
)
where the
postfix-expression
evaluates to a class object and the possibly empty
expression-list
matches
the parameter list of an
operator()
member function of the class. Thus, a call
x(arg1,...)
is interpreted
as
x.operator()(arg1, ...)
for a class object
x
of type
T
I would think that there's no technical reason to forbid this (but not being familiar with the de-facto cross-vendor C++ ABI (Itanium ABI), I can't promise anything).
There's however an evolutional issue about this at https://cplusplus.github.io/EWG/ewg-active.html#88 . It even has the [tiny] mark on it, making it a somewhat "trivial" feature under consideration.
I can't see any technical reason to forbid a static auto operator()( ... ). But it's a special case, so it would complicate the standard to add support for it. And such complication is not necessary, because it's very easy to emulate:
struct L
{
static void func() {}
void operator()() const { func(); }
operator auto () const
{
return &L::func;
}
};
See Johannes' answer for some possibly useful extra info.
Like the others, I don't see a fundamental reason why it is not possible to have a static operator(), for stateless functors or in general.
(EDIT 2020: Just found this proposal http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1169r0.html)
(UPDATE 2021: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1169r1.html)
In some cases might conflict, according to other rules, with member/static overloading which is not allowed in C++ (again, not sure why).
struct A{
void f();
static int f(); // compile error
}
So even if it were allowed to have a static operator(), should this be permitted?
struct A{
void operator()();
static int operator()(); // should be a compiler error???
}
Anyway, there is only one true reason to have a static operator() that it is not purely a syntactic reason and it is that objects should be able to call static functions as if they were member functions.
struct A{
static int f():
}
...
A a;
a.f(); // calls A::f() !!!
Specifically, the user of the class A doesn't need to know if a function is implemented as static or as a member.
It can later be upgraded to a member function from a generic point of view.
Leaving that important application to generic programming aside, there is a workaround the leads to a similar syntax that I saw in https://quuxplusone.github.io/blog/2018/03/19/customization-points-for-functions/, and that is to have a static member function called _, a name that doesn't imply any meaning.
struct A{
static int _();
}
...
A::_(); // instead of the more desirable (?) A::() or A::operator()
a._(); // this invokes the static functon _
Instead of the more desirable A::() or A::operator(), (well are they desirable at all? I don't know; something like A() would be really interesting but doens't even follow the syntax of a static function and can be confused with a constructor).
(As I said, the only feature I still miss, regarding this limitation you point out, is that a() cannot automatically delegate to a static version of the operator(), e.g. A::operator().)
In summary, your code could look like this:
struct L{
static void _() {}
auto operator()() const{
return L::_();
}
};
L ell;
ell(); // calls L::_() really.
Not sure what are willing to achieve still.
One can "CRTP" the idea https://godbolt.org/z/74vxsTYxd
#include<utility> // forward
template<class Self>
struct stateless_functor_facade{
template<class... Args>
constexpr decltype(auto) operator()(Args&&... args) const{
return Self::operator_paren(std::forward<Args>(args)...);
}
};
struct square : stateless_functor_facade<square>{
static auto operator_paren(double x){return x*x;}
};
int main(){
square s;
s(5);
}
Starting with C++23 both operator() (P1169) and operator[] (P2589) can be static. There was never really a good reason for the restriction, so it's finally being lifted.
You can also define a Lambda as static by [] static { ... }. If you have a Lambda without captures, you always should define it as static.
Unfortunately, this behavior cannot become the implicit standard without breaking API and ABI compatibility, so the explicit definition is necessary. Backwards compatibility is, as so often, both a blessing and a curse.
i i'm not going to pretend to be an expert at all. however, i was looking into static lamdas or static operator() and theirs an ongoing proposal about it. i was satisfied with what i could understand.
it appears the ideas proposed is grappling with how to design it to not break other code.etc. however it appears their working on a solution. so. mabyeeee one day!
static operator()
Document #: P1169R2
Date: 2021-08-14
Project: Programming Language C++
3 Proposal
The proposal is to just allow the ability to make the call operator a
static member function, instead of requiring it to be a non-static
member function. We have many years of experience with member-less
function objects being useful. Let’s remove the unnecessary object
parameter overhead. There does not seem to be any value provided by
this restriction.
There are other operators that are currently required to be
implemented as non-static member functions - all the unary operators,
assignment, subscripting, conversion functions, and class member
access. We do not believe that being able to declare any of these as
static will have as much value, so we are not pursuing those at this
time. We’re not aware of any use-case for making any of these other
operators static, while the use-case of having stateless function
objects is extremely common.
find full Document here:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1169r2.html
It is now possible to have static operator (), after c++23 - go to https://en.cppreference.com/w/cpp/feature_test#Language_features and look for __cpp_static_call_operator. GCC 13 will supports it - https://gcc.gnu.org/projects/cxx-status.html.
Here is an example on Compiler Explorer with gcc trunk.
struct A {
constexpr static int operator() (int x) noexcept { return x - 1; }
constexpr static int operator[] (int x) noexcept { return x - 1; }
};
int main() {
return [](int x) constexpr static noexcept { return x - 1; }( A()( A()[3] ));
}
A simple, a little bit dirty workaround until the relevant committee considers this trivial feature:
Glob operators are syntactically similar to the constructors.
Thus, you can't write a
static MyClass::operator()(...);
It was made simply impossible, because a committee decided so on unclear reasons. I would be so happy if I could talk with one of their members, to ask, what was in their mind as they decided so. Unfortunately, he probably wouldn't understand my question, because he never programmed c++. He only worked on its docs.
Now they need some decades of
debates
consultations
meetings
and considerations
to implement a trivial feature. I suspect the feature may be made available around in c++3x, and on emulated machines it may be even tried out.
Until then, you can try to write:
MyClass::MyClass(...);
In both cases you can call MyClass(...);.
Of course it is useful mainly if MyClass is a singleton. And, I would say it is a hack. Furthermore, it allocates a sizeof(MyClass) on the stack which may be bad in the performance / efficiency side.
Furthermore, this will be in essence a constructor, and constructors can't return anything. But you can avoid this by storing the result in the instance, and then casting it by a cast operator to anything you wish to.

C++ non-static method folding

Referring to this question, stackoverflow.com/q/14188612, are there situations when the compiler folds the method instantiation of two objects?
Let's say we have the following class with a private "stateless" method add, that does not modify the class members:
class Element
{
public:
Class(int a, int b) : a_(a), b_(b)
{
c_ = add(a, b);
}
private:
int add(int a, int b)
{
return a + b;
}
private:
int a_;
int b_;
int c_;
}
int main(void)
{
Element a(1, 2);
Element b(3, 4);
}
Can we sometimes expect that add will actually be compiled as a static-like method? Or, to be more clear, the address of a.add to be equal to b.add (add stored only once).
This is merely a question related to understanding compiler optimizations.
The compiler will always generate one binary method/function for add,
independent of how many objects you have. Anything else isn´t just stupid, but impossible:
The compiler can´t possibly know/calculate how many objects will exist during runtime just from the code. While it is possible with your example, more complicated programs will instantiate variables (or not) based on input given at runtime (keyboard, files...).
Note that templates can lead to more than one generation, one for each template type used in the code (but for that, the code is enough to know everything, and it has nothing to do with the object count).
When you define a method inside the class definition it usually means that the method should be inlined into each caller. The compiler can choose not to, but quite often you might find that the method doesn't actually exist in your output program at all (not true in debug builds, of course).
For non-inline member functions, the standard says
There shall be at most one definition of a non-inline member function in a program
There is no entity in C++ b.add or a.add from which you can take the address. The address-of operator needs a qualified-id to a member function of the form C::m(...) to get the address of a function. In your case, the address of add is
auto ptr = &Element::add;
and is independent from any instance. This gives a member-function pointer, which can only be used to call the function together with an object, e.g. (a.*ptr)(0,1) or (b.*ptr)(2,3) if add were a public method.

C++ restrict Semantics

I'm in the process of updating performance critical libraries to use restrict, as implemented in C++11 by g++ and MSVC with the keyword __restrict. This seems to be the most-standard-extension, so I'll use restrict and __restrict interchangeably.
restrict is a C99 keyword, but nevertheless compilers have defined important uses for it in C++.
This post intends to be a "question" asking about what each C++-specific use is and what it means, followed by a CW answer answering it. Feel free to add/check/edit. So: "Help! What do these C++ uses of the restrict keyword mean?"
Qualifying this (restrict a method):
void Foo::method(int*__restrict a) __restrict { /*...*/ }
Restrict a reference:
int&__restrict x = /*...*/;
Restrict inside a template:
std::vector<float*__restrict> x;
Restrict a member/field. This technically also applies to C's struct, but it comes up as an issue in C++ more often than it does in C:
class Foo final { public: int*__restrict field; };
Qualifying this (restrict a method):
This means that the this pointer is restricted. This one major consequence:
The method can't operate on itself as data, e.g.:
void Foo::method(Foo*__restrict other) __restrict { /*...*/ }
In that example, this might otherwise alias other. restrict is saying that you can't call this method with itself as an argument.
Note: it is okay to access or change the object, even through a field. The reason why is that the following are functionally identical:
void Foo::method1(void) __restrict { field=6; }
void Foo::method2(void) __restrict { this->field=6; }
In that example, this is not aliased with anything.
Restrict a reference:
It appears to mean exactly that--that the reference is restricted. What this exactly does and whether it's useful is another matter. Someone on this thread claims compilers can statically determine aliasing for references, and so the keyword is supposedly useless. This question was also asked about whether it should be used, but the answer "vendor specific" is hardly helpful.
There is precedent on this question. In short, in function f, the compiler knows that a.field and b.field are not aliased:
class Foo final {
int*__restrict field;
};
int f(Foo a, Foo b) { /*...*/ }
This will often be the case, assuming a!=b--for example, if field is allocated and destroyed by the constructor/destructor of Foo. Note that if field is a raw array, it will always be true and so the restrict keyword is unnecessary (and impossible) to apply.

What is the best way to deal with a library that has not marked any functions const?

I am trying to implement the use of a C++ library within my project that has not used const modifiers on its access functions. Up until now I have been using const in all of my code but this new library is causing two main problems:
Functions where the arguments are passed as const references cannot use the argument's access functions if these arguments are of a type defined by the library.
Classes with member objects of types defined by the library cannot use the access functions of these objects within a const function.
What is the best way to overcome this issue? The easiest solution would be to simply remove all use of const from my code but that would be quite frustrating to do.
Additional info: In this case I do have access to the source code and can see that the access functions do not modify anything. I omitted this information as I was interested in the more general case as well. For my scenario, const_cast appears to be the way to go
PS The library writer is not evil! It is more a bit of rough and ready code that he has kindly open sourced. I could ditch the library and use something more professional as others have noted. However, for this small time-constrained project, the simplicity of the interface to this library has made it the best choice.
How easy is it to tell whether the functions in the library actually modify anything or not?
If it's easy to tell, and they don't, then you can const_cast your const pointer/reference to non-const and call the library function. You might want to throw a wrapper around the library classes to do this for you, which is tedious and verbose but gets that code out of your classes. This wrapper could perhaps be a subclass that adds some const accessors, depending whether the way you use the library class allows that to work.
If it's hard to tell, or they do modify things, then you need to use non-const instances and references to the library classes in your code. mutable can help with those of type (2), but for those of type (1) you just need to pass non-const arguments around.
For an example of why it might be hard, consider that the library author might have written something like this:
struct Foo {
size_t times_accessed;
int value;
int get() {
++times_accessed;
return value;
}
};
Now, if you const_cast a const instance of Foo and call get(), you have undefined behavior[*]. So you have to be sure that get really doesn't modify the object it's called on. You could mitigate this a bit, by making sure that you never create any const instances of Foo, even though you do take const references to non-const instances. That way, when you const_cast and call get you at least don't cause UB. It might make your code confusing, that fields keep changing on objects that your functions claim not to modify.
[*] Why is it undefined behavior? It has to be, in order that the language can guarantee that the value of a const object never changes in a valid program. This guarantee allows the compiler to do useful things. For example it can put static const objects in read-only data sections, and it can optimize code using known values. It also means that a const integer object with a visible initializer is a compile-time constant, which the standard makes use of to let you use it as the size of an array, or a template argument. If it wasn't UB to modify a const object, then const objects wouldn't be constant, and these things wouldn't be possible:
#include <iostream>
struct Foo {
int a;
Foo(int a) : a(a) {}
};
void nobody_knows_what_this_does1(const int *p); // defined in another TU
void nobody_knows_what_this_does2(const int *p); // defined in another TU
int main() {
const Foo f(1);
Foo g(1);
nobody_knows_what_this_does1(&f.a);
nobody_knows_what_this_does2(&g.a);
int x;
if (std::cin >> x) {
std::cout << (x / f.a); // Optimization opportunity!
std::cout << (x / g.a); // Cannot optimize!
}
}
Because f is a const object, and hence f.a is a const object, the optimizer knows that f.a has value 1 when it's used at the end of the function. It could, if it chose, optimize away the division. It doesn't know the same thing about g.a: g is not a const object, a pointer to it has been passed into unknown code, so its value might have changed. So if you're the author of nobody_knows_what_this_does1 or nobody_knows_what_this_does2, and you're thinking of const_casting p and using it to modify its referand, then you can only do it if you somehow know that the referand is non-const. Which normally you don't, so normally you don't use const_cast.
I think you have the following options:
If you are sure the library is working as it should if it was using the const specifier, you could use const_cast<> to remove the const-ness of your objects when dealing with the library
Alternatively, you could make non-const copies of your const objects and pass those to the library, then update the changes to the non-const parts on your original objects
Search for another library that is const-correct
remove all const from your code (not recommended)
Another option is to copy your object into a modifiable temp and pitch it. This is probably the safest thing to do if you're in the circumstance where your class offers a copy constructor and it's not too expensive. This has been my preferred method when it's available, as I know it's 100% safe. Silly example:
int getInfoFromString(String& str); //what?? why isn't str const :(
So I do
String temp(str);
int stuffINeed = getInfoFromString(temp);
//happy
If the library's interface is not big, you can create a wrapper, where you would adjust your code to expected types, by either casting or making a copy of parameters, which are passed to library's functions.
But do not degrade your code in order to use the library.
Another suggestion: Are you familiar with the mutable keyword? If you use it correctly, it might actually accomplish exactly what you're trying to do, with exactly one word added to your code. This keyword can evoke religious opinion at the level of goto because it's probably used as a kludge for every hundred times that it's used because it really is the best design option. In your case, it's debatable which it is but I think it fits the spirit: your annoying library object is something that can be fake-modified without breaking the semantic const-ness of your methods, so go ahead.
class Outer {
mutable Inner inner;
public void foo() const {
inner.nonConstMethod(); //compiles because inner is mutable
}
};

What does the const operator mean when used with a method in C++?

Given a declaration like this:
class A {
public:
void Foo() const;
};
What does it mean?
Google turns up this:
Member functions should be declared with the const keyword after them if they can operate on a const (this) object. If the function is not declared const, in can not be applied to a const object, and the compiler will give an error message.
But I find that somewhat confusing; can anyone out there put it in better terms?
Thanks.
Consider a variation of your class A.
class A {
public:
void Foo() const;
void Moo();
private:
int m_nState; // Could add mutable keyword if desired
int GetState() const { return m_nState; }
void SetState(int val) { m_nState = val; }
};
const A *A1 = new A();
A *A2 = new A();
A1->Foo(); // OK
A2->Foo(); // OK
A1->Moo(); // Error - Not allowed to call non-const function on const object instance
A2->Moo(); // OK
The const keyword on a function declaration indicates to the compiler that the function is contractually obligated not to modify the state of A. Thus you are unable to call non-const functions within A::Foo nor change the value of member variables.
To illustrate, Foo() may not invoke A::SetState as it is declared non-const, A::GetState however is ok because it is explicitly declared const. The member m_nState may not be changed either unless declared with the keyword mutable.
One example of this usage of const is for 'getter' functions to obtain the value of member variables.
#1800 Information: I forgot about mutable!
The mutable keyword instructs the compiler to accept modifications to the member variable which would otherwise cause a compiler error. It is used when the function needs to modify state but the object is considered logically consistent (constant) regardless of the modification.
This is not an answer, just a side comment. It is highly recommended to declare variables and constants const as much as possible.
This communicates your intent to users of your class (even/especially yourself).
The compiler will keep you honest to those intentions. -- i.e., it's like compiler checked documentation.
By definition, this prevents state changes you weren't expecting and can, possibly, allow you to make reasonable assumptions while in your methods.
const has a funny way of propagating through your code. Thus, it's a really good idea to start using const as early and as often as possible. Deciding to start const-ifying your code late in the game can be painful (easy, but annoying).
If you're using a language with static, compile time checks it's a great idea to make as much use of them as possible... it's just another kind of testing really.
Functions with const qualifier are not allowed to modify any member variables. For example:
class A
{
int x;
mutable int y;
void f() const
{
x = 1; // error
y = 1; // ok because y is mutable
}
};
C++ objects can be declared to be const:
const A obj = new A();
When an object is const, the only member functions that can be called on that object are functions declared to be const. Making an object const can be interpreted as making the object readonly. A const object cannot be changed, i.e. no data members of the object can be changed. Declaring a member function const means that the function is not allowed to make any changes to the data members of the object.
Two suggested best practices from experience:
(1) Declare const functions whenever possible. At first, I found this to be just extra work, but then I started passing my objects to functions with signatures like f(const Object& o), and suddenly the compiler barfed on a line in f such as o.GetAValue(), because I hadn't marked GetAValue as a const function. This can surprise you especially when you subclass something and don't mark your version of the virtual methods as const - in that case the compile could fail on some function you've never heard of before that was written for the base class.
(2) Avoid mutable variables when it's practical. A tempting trap can be to allow read operations to alter state, such as if you're building a "smart" object that does lazy or asynchronous i/o operations. If you can manage this with only one small mutable variable (like a bool), then, in my experience, this makes sense. However, if you find yourself marking every member variable as mutable in order to keep some operations const, you're defeating the purpose of the const keyword. What can go wrong is that a function which thinks it's not altering your class (since it only calls const methods) my invoke a bug in your code, and it could take a lot of effort to even realize this bug is in your class, since the other coder (rightly) assumes your data is const because he or she is only calling const methods.
const has a funny way of propagating through your code. Thus, it's a really good idea to start using const as early and as often as possible. Deciding to start const-ifying your code late in the game can be painful (easy, but annoying).
Additionally, you will easily run into problems if methods that should be const aren't! This will creep through the code as well, and make it worse and worse.
that will cause the method to not be able to alter any member variables of the object