【问题标题】:Invoking a class template member function pointer through operator()通过 operator() 调用类模板成员函数指针
【发布时间】:2018-12-16 02:37:16
【问题描述】:

我有一组课程;一个是模板,并接受其他两个类作为其模板参数。类模板有一个函数指针成员,它将指向T 类的函数。我正在尝试通过类的operator()() 调用函数调用。

这是我的代码到目前为止的样子:

template<class T>
class A {
private:
    T* ptrT{ nullptr };
public:
    explicit A( T t ) : ptrT( &t ) {}

    void(T::*func)();

    void operator()() {
        (ptrT->*func)();
    }    
};

class B {
    int ib{2};
public:
    void func() {
        std::cout << ib << '\n';
    }
};

class C {
    int ic{6};
public:
    void func() {
        std::cout << ic << '\n';
    }
};

int main() {
    try {
        B b;
        C c;
        A<B> a1( b );
        A<C> a2( c );
        a1.func = &B::func;
        a2.func = &C::func;

        a1();
        a2();   

    } catch( std::runtime_error& e ) {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;    
}

到目前为止,这已编译,但似乎输出显示的是函数指针的地址,而不是值...

-输出-

// 1st Run
20326695
20326703

// 2nd Run
2304295
2304303

// 3rd Run
1780007
1780015

我知道要获得实际值,我必须尊重某些东西,但是由于类成员函数指针的语法有点晦涩,我不知道需要尊重什么,也不知道正确的语法......我会感谢任何帮助!

【问题讨论】:

  • 你在A的构造函数中的参数T t是传值的。您正在获取并保存局部变量的地址到ptrT。由于未定义的行为,您得到的结果是垃圾。我认为这是T&amp; t 的错字。
  • @user10605163 嗯好吧...我会尝试通过引用传递,看看是否有什么不同。
  • @user10605163 成功了!我有一种感觉,这是我遗漏或忽略的简单事物。这不是错字。我只是没有考虑将本地副本传递给构造函数,而不是通过引用传递。我更关注成员函数指针语法,而忽略了更简单的东西。

标签: c++ member-function-pointers class-template


【解决方案1】:

User 在 cmets 中提供了我所缺少的内容。它与成员函数指针的语法无关,也与如何调用或遵守它们以获得正确的值无关。

这是我忽略或错过的简单事情。问题出在我的类模板的构造函数中。我通过值而不是引用传递,因此得到UB。它正在复制本地副本的地址并将其保存到成员指针中。修复上述代码需要做的就是:

我不得不改变这个:

explicit A( T t ) : ptrT( &t ) {}

到这里:

explicit A( T& t ) : ptrT( &t ) {}

现在一切都按预期工作,我现在得到了正确的结果。

【讨论】:

    猜你喜欢
    • 2017-03-30
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    • 2015-02-25
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    相关资源
    最近更新 更多