简体   繁体   中英

Cast const member function to non-const

Is casting the const ness of member function pointers defined in C++? Is the following valid code?

struct T {
  void foo(int i) const { std::cout << i << std::endl;};
};

void (T::*f1)(int) const = &T::foo;
void (T::*f2)(int)       = reinterpret_cast<void (T::*)(int)>(f1);
T t;
(t.*f2)(1);

Update:

The reason why I need this is that I'm writing a function that accepts both an object and a member function pointer to that object. I need a version for const objects (accepting only const functions) and a normal one. Since I don't want duplicate code, my idea was to put the actual code in the non-const version and call it from the const one, casting away any consts.

Compiler eats it. But the backward cast is more useful.

And again but - it is better to don't use it, const_cast is usually just a quick and dirty solution, which you apply only when there are not any other solution.

Answer to update

If I understand you correctly you are going to use one object and two function. First function accepts const object and const member-function, second - non-const object and non-const member-function.

According to given information you can change second function to accept non-const object and const member-function. And give them one non-const object and its const member-function.

是的,它是定义的,但如果函数真的是const,你可能不希望它,因为一些编译器优化(即返回值缓存)依赖于函数是const。

I don't see a reason for doing this: even if you could, you'd make it more restrictive. Let's say you have a class Foo:

class Foo {
  void f() const;
  void g();
}

And some snippet of code:

Foo a;
const Foo b;

Then you can call both af() and ag() , but not bg() because b is const . As you can see, placing const after a member function makes it less restrictive, not more.

And, by reinterpret_cast ing this pointer, you'll get the pointer with exact same value(due to the nature of reinterpret_cast ), and if you try to call it, you'll get into the same T::foo()

You can do it, but it has no meaning, wherever you can call f2, you can also call f1 too. You should cast in the other way. But if something, you should cast the object, not the function.

void (T::*f1)(int) const = &T::foo;
void (T::*f2)(int)       = reinterpret_cast<void (T::*)(int)>(f1);
T t;
(t.*f2)(1); // compiles
(t.*f1)(1); // this compiles too!!

but if you have

const T t;
(t.*f2)(1); // error t is const
(t.*f1)(1); // still compiles

The only was to resolve the ambiguity is to perform a static_cast, this is basically a language feature

#include <boost/typeof/typeof.hpp>
struct Test
{
    const int& foo();
    const int& foo() const;
};

int main()
{
    typedef const int&(Test::*non_const_ptr)();
    typedef const int&(Test::*const_ptr)()const;
    BOOST_TYPEOF(static_cast<non_const_ptr>(&Test::foo)) ss;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM