我想做这样的事情:
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
做这个额外的部分,我不想将这些方法添加到其他可能的 T
。我无法进行转换,因为可能的 T
不是继承类型。
我知道我可以使用外部帮助模板来适应这个:
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
的私有(private)成员(不能调用 DoSomeFooPrivateThing
),这限制了它的功能,并且它被公开给外面,这不是很漂亮。 (将外部方法作为 friend 只会让事情变得更糟。)
另一个看似合理的选择是在内部实现它:
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();
}
你可以直接使用(这里不需要使用template
):
void DoSomethingImpl(ClassA& t)
{
t.DoThingOne();
t.DoThingTwo();
DoSomeFooPrivateThing();
t.DoThingThree();
}
关于c++ - 模板元代码和私有(private)成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29294013/