具有唯一静态成员的C++模板



模板类的每个实例都复制了所有静态成员。如果我想要一个静态成员对所有实例只存在一次,我该怎么办?是否在类模板之外使用普通静态字段?可以工作,但似乎不合法,因为没有更多的关联到模板类。有没有一种方法可以将这种唯一的静态成员与模板类关联起来?

否;每个模板类都是一个完全独立的对象。

您可以使用静态成员创建一个公共祖先类:

class Parent
{
public:
  static int commonStatic;
};
template <typename T>
class MyTempl : public Parent
{
  static int nonSharedStatic;
};

模板类的每个实例都复制了所有静态成员。

没有。每个专业化都有不同的静态特性,但不同的专业化是不同的类。毫无疑问,vector<int>vector<char>是完全分离的。把它想象成写IntVectorCharVector

编辑:不要对此使用继承。仅仅为了共享静态成员而引入基类肯定是错误的做法。

如果你想在不同的类之间共享东西,就像你通常做的那样。在第三个类中封装一些静态,就这样了。

为模板类定义一些基类。在这个基类中包括所有常见成员:

class ExampleBase {
public:
   static int foo;
};
int ExampleBase::foo = 0;
template <class A>
class Example : private ExampleBase {
public:
    static void setFoo(int f) { foo = f; }
    static int getFoo() { return foo; }
};

则每个示例实例都具有公共静态成员ExampleBase::foo:

int main() {
    Example<int>::setFoo(7);
    assert(Example<float>::getFoo() == 7);
};

将全局变量放在某个位置。

类似这样的东西:

#include <iostream>
// header.hpp
extern int someValue;
template< typename T >
struct A
{
  int foo() const
  {
    return someValue;
  }
};
// source.cpp
int someValue = 5;
int main()
{
  std::cout << A< float >().foo() << std::endl;
  std::cout << A< int >().foo() << std::endl;
}

是否在类模板之外使用普通静态字段?

确切地说;只需将其放入模板声明之外的函数中即可。

如果真的想在这种情况下限制访问,你可以使用这样的东西:

class t_shared {
    static int& Shared() {
        static int s(0);
        return s;
    }
public:
    template < typename T >
    class t_template {
    public:
        void f() {
            std::cout << ++Shared() << std::endl;
        }
    };
};
int main(int argc, const char* argv[]) {
    t_shared::t_template<int>().f();
    return 0;
}

类模板在静态成员方面实际上与普通类有点不同。即使每个翻译单元都包含foo.hpp,以下内容也非常好:

foo.hpp:

template <typename T> struct TmplFoo
{
    static double d;
};
struct OrdFoo
{
    static double e;
}

foo.cpp:

#include "foo.hpp"
double OrdFoo::e = -1.5;

请注意,我们从不需要单独定义TmplFoo<T>::d。链接器知道如何计算对TmplFoo<T>::d的所有本地引用(对于给定的T)都引用同一个对象。

最新更新