假设我有一个基类存储对某些 class Bar
的引用:
class FooBase
{
public:
FooBase( Bar &ctx ) : _barCtx( ctx ) {};
virtual ~FooBase() {};
// Some other functions
protected:
Bar &_barCtx;
};
我想做的是在此之上添加一个继承级别,其中 class Foo<T>
会增加一些功能。
template< typename T >
class Foo : public FooBase
{
public:
Foo( Bar &ctx ) : FooBase( ctx ) {};
bool doSomething( int a );
};
然后,有一些实例 Foo<T>
需要提供不同版本的 doSomething()
, 因此使用了模板特化。问题是,在 Foo<>
的每个专门版本中, 我必须重新实现构造函数并传递 Bar
的引用到 super 类。这基本上是复制和粘贴代码,我想避免这种情况。
class Baz;
template<>
class Foo<Baz> : public FooBase
{
public:
Foob( Bar &ctx ) : FooBase( ctx ) {};
bool doSomething( std::string &str, int x, float g );
};
此练习的重点是提供不同类型的 doSomething()
,具有不同的签名。那么,如果不使用 C++11(因为我坚持使用 GCC 4.6.3),有没有办法避免这种代码重复?或者,是否有更好的方式提供不同的 doSomething()
?
最佳答案
我实际上认为 SFINAE 方法更好,但如果出于某种原因这对您不起作用,那么专门化类模板的各个成员函数可能适合您。但是,您必须在通用模板中声明所有重载,然后提供适当的定义。这将确保您在调用错误的重载时会收到链接错误。
另一种选择是使用 CRTP。该方法在下面进一步展示。
成员特化方法:
#include <string>
class Bar {};
class FooBase
{
public:
FooBase( Bar &ctx ) : _barCtx( ctx ) {};
virtual ~FooBase() {};
protected:
Bar &_barCtx;
};
template< typename T >
class Foo : public FooBase
{
public:
Foo( Bar &ctx ) : FooBase( ctx ) {};
bool doSomething( int a ) { return true; }
// Declared, but not defined.
bool doSomething( std::string &str, int x, float g );
};
class Baz {};
// Declared, but not defined.
template <>
bool
Foo<Baz>::doSomething(int i);
template <>
bool
Foo<Baz>::doSomething(std::string &str, int x, float g) {
return true;
}
int main() {
Bar b;
Foo<int> f1(b);
std::string s;
f1.doSomething(1); // Compiles.
// f1.doSomething(s, 1, 3.14f); // Link error.
Foo<Baz> f2(b);
// f2.doSomething(1); // Link error.
f2.doSomething(s, 1, 3.14f); // Compiles.
}
CRTP 方法:
#include <string>
class Bar {};
class Baz {};
template <typename T>
class Spec {
public:
bool doSomething( int a );
};
template <>
class Spec<Baz> {
public:
bool doSomething( std::string &str, int x, float g );
};
class FooBase {
public:
FooBase( Bar &ctx ) : _barCtx( ctx ) {};
virtual ~FooBase() {};
protected:
Bar &_barCtx;
};
template< typename T >
class Foo : public FooBase, public Spec<T> {
public:
Foo( Bar &ctx ) : FooBase( ctx ) {};
};
template <typename T>
bool Spec<T>::doSomething( int a ) {
Foo<T> *fp = static_cast<Foo<T> *>(this);
return true;
}
bool Spec<Baz>::doSomething( std::string &str, int x, float g ) {
Foo<Baz> *fp = static_cast<Foo<Baz> *>(this);
return true;
}
int main() {
Bar b;
std::string s;
Foo<int> f1(b);
f1.doSomething(1);
Foo<Baz> f2(b);
f2.doSomething(s, 1, 3.14f);
}
关于c++ - 避免模板特化中的构造函数重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23501779/