c++ - 避免模​​板特化中的构造函数重复

标签 c++ templates template-specialization

假设我有一个基类存储对某些 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/

相关文章:

wpf - DataTemplateSelector 不会被使用

c++ - 如何保证 C++ 模板类特化之间的接口(interface)一致?

c++ - 具有完全专用别名的实现切换

C++:在通用代码中获取对象大小的最佳方法

c++ - 如何将运算符作为默认仿函数参数传递?

c++ - 依赖于构造函数参数的模板类特化?

c++ - 使用CodeBlocks编译64位DLL会导致链接器错误

c++ - 长长除错

c++如何创建包含大小未初始化字节的std::string?

c++ - 使用多个描述符集与更多统一更新