1

模板类为它的每个实例复制了所有静态成员。如果我想要一个对所有实例只存在一次的静态成员,我该怎么办?在类模板之外使用普通的静态字段?会工作,但似乎不优雅,因为没有更多与模板类的关联。有没有办法以某种方式将这种独特的静态成员与模板类相关联?

4

6 回答 6

4

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

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

class Parent
{
public:
  static int commonStatic;
};

template <typename T>
class MyTempl : public Parent
{
  static int nonSharedStatic;
};
于 2012-08-23T13:26:01.080 回答
1

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

没有。每个专业化都有不同的静态,但不同的专业化是不同的类。别搞错了,vector<int>而且vector<char>完全分开的。把它想象成写作IntVectorCharVector

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

如果您希望在不同的班级之间共享内容,请像通常那样做。在第三个类中包装一些静态,就是这样。

于 2012-08-23T13:23:04.543 回答
1

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

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; }
};

然后每个 Example 实例都有共同的静态成员ExampleBase::foo

int main() {
    Example<int>::setFoo(7);
    assert(Example<float>::getFoo() == 7);
};
于 2012-08-23T13:25:12.877 回答
0

在某处放置一个全局变量。

像这样的东西:

#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;
}
于 2012-08-23T13:27:58.087 回答
0

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

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

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

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;
}
于 2012-08-23T13:28:27.993 回答
-1

类模板在静态成员方面实际上与普通类有点不同。以下内容非常好,即使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)的所有本地引用都指向同一个对象。

于 2012-08-23T13:34:35.047 回答