5

是否强制转换constC++ 中定义的成员函数指针?以下是有效代码吗?

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);

更新:

我需要这个的原因是我正在编写一个函数,它接受一个对象和一个指向该对象的成员函数指针。我需要一个用于 const 对象的版本(只接受 const 函数)和一个普通的版本。由于我不想要重复的代码,我的想法是将实际代码放在非常量版本中并从 const 版本中调用它,丢弃任何 const。

4

5 回答 5

3

编译器吃掉它。但是向后转换更有用。

再一次但是 - 最好不要使用它, const_cast 通常只是一个快速而肮脏的解决方案,只有在没有任何其他解决方案时才应用它。

回答更新

如果我理解正确,您将使用一个对象和两个函数。第一个函数接受 const 对象和 const 成员函数,第二个 - 非常量对象和非常量成员函数。

根据给定的信息,您可以更改第二个函数以接受非常量对象和 const 成员函数。并给他们一个非常量对象及其 const 成员函数。

于 2012-08-11T13:10:25.397 回答
1

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

于 2012-08-11T13:05:41.470 回答
0

可以,但是没有意义,哪里可以调用f2,也可以调用f1。你应该以另一种方式投射。但是如果有的话,你应该转换对象,而不是函数。

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!!

但如果你有

const T t;
(t.*f2)(1); // error t is const
(t.*f1)(1); // still compiles
于 2012-08-11T13:27:52.660 回答
0

解决歧义的唯一方法是执行 static_cast,这基本上是一种语言功能

#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;
}
于 2015-07-29T02:39:15.297 回答
-1

我看不出这样做的理由:即使你可以,你也会使其更具限制性。假设你有一个类 Foo:

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

还有一些代码片段:

Foo a;
const Foo b;

然后你可以同时调用a.f()and a.g(),但不能b.g()因为bis const。如您所见,放在const成员函数之后会减少限制,而不是增加限制。

而且,通过reinterpret_casting 这个指针,您将获得具有完全相同值的指针(由于 的性质reinterpret_cast),如果您尝试调用它,您将进入相同的 T::foo()

于 2012-08-11T13:09:02.637 回答