【问题标题】:Class member function as a template parameter in case of inheritance类成员函数在继承的情况下作为模板参数
【发布时间】:2019-09-06 14:46:18
【问题描述】:

如果函数在基类中实现,如何将函数指针作为模板参数传递。

template<class T, int(T::* FUNC)() const>
int TestFunc(const T& _v)
{
    return (_v.*FUNC)();
}

struct A
{
    int F() const   { return 100; }
};

struct B : public A {};

int main()
{
    B b;
    int32_t value = TestFunc<B, &B::F>(b);
    cout << value;
    //...
}

得到错误 C2672: 'TestFunc': 找不到匹配的重载函数。

如果 VS 编译器 static_cast 有帮助:

typedef int(B::* BF)() const;
int32_t value = TestFunc<B, static_cast<BF>(&B::F)>(b);

这些都已成功构建并运行,但我需要使用 clang 构建它。

有什么想法吗?

附: BF bf = &amp;B::F; 此转换无需强制转换即可工作,因此编译器理解类 B 具有方法 F。但它不能用作模板参数。

更新:P.P.S.实际的类和代码更复杂。上面的例子只是一个非常简化的版本来概述问题。

解决方法:我使用的当前解决方法是覆盖 B 类中的 F(),它只是调用继承,但仍在寻找更好的解决方案。

【问题讨论】:

  • 不知道,但也许你能找到一些有趣的东西here

标签: c++ templates c++14


【解决方案1】:

一种选择是只使用A 作为模板参数:

int32_t value = TestFunc<A, &A::F>(b);

【讨论】:

    【解决方案2】:

    由于您在调用中明确指定了两个模板参数,也许您可​​以让编译器为您推断成员函数类型:

    template<class T, class P>
    int TestFunc(const T& _v, P p) {
        return (_v.*p)();
    }
    

    然后:

    int32_t value = TestFunc(b, &B::F);
    

    【讨论】:

    • 在实际代码中,TestFunc 是一个大类,而 FUNC 用于大约剂量的函数。然后这个类被其他几个类继承。建议的解决方案将需要大量重构:(
    【解决方案3】:

    看起来它不会按原样工作。

    有可能的解决方法:

    • @Maxim Egorushkin 的那个
    • 另一个是使用额外的模板函数包装器,它接受 B& 并在内部调用 F:
        template<class T, int(*FUNC)(const T&) const>
        int TestFunc(const T& _v)
        {
            return (*FUNC)(_v);
        }
    
        template <class T>
        int F_Wrapper(const T& obj)
        {
            return obj.F();
        }
    
        ...
    
        int value = TestFunc < B, &F_Wrapper<B>>(b);
    
    • 但最简单的方法还是在 B 类中重写 F 函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-13
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 2023-01-15
      • 2011-07-06
      相关资源
      最近更新 更多