c – 模板元代码和私有成员

我想做这样的事情:
template <typename T>
class Foo
{
...
public:
    void DoSomething()
    {
        compile_time_if (T is ClassA)
        {
            m_T.DoThingOne();
            m_T.DoThingTwo();
        }
        DoSomeFooPrivateThing();
        m_T.DoThingThree();
    }
    T m_T;
};

在这种情况下,我知道所有有效的T实现DoThingThree,但只有ClassA实现DoThingOne和DoThingTwo.这不是一个鸭子类型的东西,我只想为ClassA做这个额外的部分,我不想将这些方法添加到其他可能的Ts.我不能做转换,因为可能的Ts不是继承类型.

我知道我可以使用外部帮助器模板来满足这个要求:

template <typename T>
void Foo_DoSomething(T& t)
{
    t.DoThingThree();
}

template <>
void Foo_DoSomething(ClassA& t)
{
    t.DoThingOne();
    t.DoThingTwo();
    t.DoThingThree();
}

template <typename T>
class Foo
{
...
public:
    void DoSomething()
    {
        Foo_DoSomething(m_T);
    }
...
};

但是现在这个外部模板无权访问Foo的私有成员(无法调用DoSomeFooPrivateThing),这限制了它的功能,并且它公开暴露给外部,这并不漂亮. (将外部方法变成朋友会让事情变得更糟.)

一个看似合理的选择是在内部实施:

template <typename T>
class Foo
{
...
public:
    void DoSomething()
    {
        DoSomethingImpl(m_T);
    }
...
private:
    template <typename T2>
    void DoSomethingImpl(T2& t)
    {
        DoSomeFooPrivateThing();
        t.DoThingThree();
    }

    template <>
    void DoSomethingImpl(ClassA& t)
    {
        t.DoThingOne();
        t.DoThingTwo();
        DoSomeFooPrivateThing();
        t.DoThingThree();
    }
...
};

但这需要复制外部模板类型和参数.这可能是可以接受的,但它仍然感觉有点奇怪.遗憾的是它实际上并没有编译(至少在GCC中没有编译,因为它反对类中的特化).

一个更好的方法吗?

解决方法

我认为你的最后一个选择是最好的选择.

代替

template <>
void DoSomethingImpl(ClassA& t)
{
    t.DoThingOne();
    t.DoThingTwo();
    DoSomeFooPrivateThing();
    t.DoThingThree();
}

你可以使用(这里不需要使用模板):

void DoSomethingImpl(ClassA& t)
{
    t.DoThingOne();
    t.DoThingTwo();
    DoSomeFooPrivateThing();
    t.DoThingThree();
}

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...