Mir*_*ral 7 c++ templates c++11 c++03
我想做这样的事情:
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;
};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我知道所有有效的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);
}
...
};
Run Code Online (Sandbox Code Playgroud)
但是现在这个外部模板无权访问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();
}
...
};
Run Code Online (Sandbox Code Playgroud)
但这需要复制外部模板类型和参数.这可能是可以接受的,但它仍然感觉有点奇怪.遗憾的是它实际上并没有编译(至少在GCC中没有编译,因为它反对类内的特化).
有一个更好的方法吗?
我认为你的最后一个选择是最好的。
代替
template <>
void DoSomethingImpl(ClassA& t)
{
t.DoThingOne();
t.DoThingTwo();
DoSomeFooPrivateThing();
t.DoThingThree();
}
Run Code Online (Sandbox Code Playgroud)
你可以直接使用(不需要在template这里使用):
void DoSomethingImpl(ClassA& t)
{
t.DoThingOne();
t.DoThingTwo();
DoSomeFooPrivateThing();
t.DoThingThree();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
235 次 |
| 最近记录: |