模板/泛型类中的非常量静态成员-c ++ vs c# [英] non-constant static members in template/generic class - c++ vs c#

查看:171
本文介绍了模板/泛型类中的非常量静态成员-c ++ vs c#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在c#中,静态成员对于每个泛型类都是唯一的,就像这个例子中的那样

  using System; 

//泛型类
public class GenTest< T>
{
//静态变量 - 将在折射中为每种类型创建
static CountedInstances OnePerType = new CountedInstances();

//数据成员
私人T mT;

//简单构造函数
公共GenTest(T pT)
{
mT = pT;



// a类
公共类CountedInstances
{
//静态变量 - 每个实例会增加一次
public static int Counter;

//简单构造函数
public CountedInstances()
{
//在对象实例化期间增加一个计数器
CountedInstances.Counter ++;
Console.WriteLine(Counter);



public class staticTest {
static void Main(string [] args){
//主代码入口点
//在执行结束时,CountedInstances {{Not a typo |。}}计数器= 2
GenTest< int> g1 =新的GenTest< int>(1);
GenTest< int> g11 =新的GenTest< int>(11);
GenTest< int> g111 =新的GenTest< int>(111);
GenTest< double> g2 =新的GenTest< double>(1.0);


from http://en.wikipedia.org/wiki/Generic_programming



C ++?我已经尝试过检查自己,但是翻译为c ++似乎忽略了静态成员。

  #include< iostream> 
使用namespace std;

类CountedInstances {
public:
static int Counter;
CountedInstances(){
Counter ++;
cout<<计数器<< ENDL;
}
};

int CountedInstances :: Counter = 0;

模板< class T> class GenTest {
static CountedInstances OnePerType;
T mT;
public:
GenTest(T pT){
mT = pT;
}
};

模板< class T> CountedInstances GenTest< T> :: OnePerType = CountedInstances();

int main(){
GenTest< int> G1(1);
GenTest< int> G11(11);
GenTest< int> G111(111);
GenTest< double> G2(1.0);
cout<< CountedInstances :: Counter<< ENDL;
// CountedInstances c1;
// CountedInstances c2;

answer 我可以看到,在c ++中,静态成员对于每个专业化都是唯一的,但是,我的代码似乎是合法的,但静态成员 OnePerType 是我认为每个 GenTest<> 计数器将被打印,只有当我创建对象时才会发生什么类型为 CountedInstances ,如注释中所示。为什么会这样?

解决方案

From IBM C ++编译器参考资料(强调我的):


如果编译器隐式地实例化一个包含静态成员的类模板,那么这些静态成员不是隐式实例化的 EM>。只有当编译器需要静态成员的定义时,编译器才会实例化一个静态成员


编译器有效地实例化 GenTest :: OnePerType GenTest< double> :: OnePerType ,您必须以某种方式参考它们。例如,您可以在构造函数中添加(void)& OnePerType; (现场示例: http://ideone.com/CWNr7U )。




编辑: 感谢 chris.schuette 这里是来自C ++标准的引用(检查N3337),§14.7.1(强调我的):
$ b


1(...)类模板专门化的隐式实例化会导致类成员函数,成员类,成员范围成员枚举,静态数据成员的声明的隐式实例化,而不是定义或默认参数 和会员模板; (...)

<8>类模板的隐式实例化不会导致该类的任何静态数据成员被隐式地实例化为



In c# static members are unique for each generic class like in this example

using System;

//A generic class
public class GenTest<T>
{
  //A static variable - will be created for each type on refraction
  static CountedInstances OnePerType = new CountedInstances();

  //a data member
  private T mT;

  //simple constructor
  public GenTest(T pT)
  {
    mT = pT;
  }
}

//a class
public class CountedInstances
{
  //Static variable - this will be incremented once per instance
  public static int Counter;

  //simple constructor
  public CountedInstances()
  {
    //increase counter by one during object instantiation
    CountedInstances.Counter++;
    Console.WriteLine(Counter);
  }
}

public class staticTest {
  static void Main(string[] args) {
    //main code entry point
    //at the end of execution, CountedInstances{{Not a typo|.}}Counter = 2
    GenTest<int> g1 = new GenTest<int>(1);
    GenTest<int> g11 = new GenTest<int>(11);
    GenTest<int> g111 = new GenTest<int>(111);
    GenTest<double> g2 = new GenTest<double>(1.0);
  }
}

from http://en.wikipedia.org/wiki/Generic_programming

What about c++? I have tried out to check that myself but translation to c++ seems to ignore the static member.

#include <iostream>
using namespace std;

class CountedInstances {
public:
  static int Counter;
  CountedInstances() {
    Counter++;
    cout << Counter << endl;
  }
};

int CountedInstances::Counter = 0;

template<class T> class GenTest {
  static CountedInstances OnePerType;
  T mT;
public:
  GenTest(T pT) {
    mT = pT;
  }
};

template<class T> CountedInstances GenTest<T>::OnePerType = CountedInstances();

int main() {
  GenTest<int> g1(1);
  GenTest<int> g11(11);
  GenTest<int> g111(111);
  GenTest<double> g2(1.0);
  cout << CountedInstances::Counter << endl;
  //CountedInstances c1;
  //CountedInstances c2;
}

In this answer I can see that in c++ static members are unique for each specialization, however, my code seems legit but the static member OnePerType is ignored.

I thought that for each GenTest<> Counter will be printed what happens only when I create objects of type CountedInstances as in the comment. Why is that?

解决方案

From IBM C++ compilers reference (emphasis mine):

If the compiler implicitly instantiates a class template that contains static members, those static members are not implicitly instantiated. The compiler will instantiate a static member only when the compiler needs the static member's definition.

So to force the compiler to effectively instantiate GenTest<int>::OnePerType and GenTest<double>::OnePerType, you have to reference them somehow. For example you can add (void)&OnePerType; in the constructor (live example: http://ideone.com/CWNr7U).


Edit: Thanks to chris.schuette here's a quote from the C++ Standard (checked for N3337), § 14.7.1 (emphasis mine):

1 (...) The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions or default arguments, of the class member functions, member classes, scoped member enumerations, static data members and member templates; (...)

8 The implicit instantiation of a class template does not cause any static data members of that class to be implicitly instantiated.

这篇关于模板/泛型类中的非常量静态成员-c ++ vs c#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆