【发布时间】:2014-02-20 07:09:52
【问题描述】:
我有两个具有静态成员实例的类的测试用例。第一个使用非模板样本,而第二个依赖于通用对象类型。
困境很简单:静态成员的构造函数在主函数之前被调用(应该如此),但只针对特定的对象类型。泛型类型不表现出相同的行为。事实上,构造函数根本没有被编译。似乎编译器决定完全忽略它作为(不完全合理的)优化的一种手段。
我想知道发生了什么,以及可以做些什么来使它以最优雅的方式工作。我认为显而易见的答案是:在代码的某处使用该静态成员。我不想这样做,因为特定类型的情况在不使用该静态成员的情况下工作,除了在其构造函数中执行一些“工作”。
代码示例:
//////////////////////////////////////////////
// Specific case
//////////////////////////////////////////////
class CPassive
{
public:
CPassive()
{
printf(" passively called ");
}
};
class CActive
{
private:
static CPassive ms_passive;
};
CPassive CActive::ms_passive;
///////////////////////////////////////////////////////////
// GENERIC TYPES
///////////////////////////////////////////////////////////
class CSample
{
public:
CSample()
{
printf("sample ");
}
};
template <typename T>
class CGenericPassive
{
public:
CGenericPassive()
{
T sample;
printf(" generic passive .. ");
}
private:
};
template <typename T>
class CGenericActive
{
private:
static CGenericPassive<T> ms_passive;
};
template<typename T>
CGenericPassive<T> CGenericActive<T>::ms_passive;
int main(int argc, char** argv)
{
CActive activeExample;// instantiates the static member
CGenericActive<CSample> activeExample; // obliterates the static from the class def.
}
【问题讨论】:
-
我想我还没有完全理解。对于泛型类型,您希望运行多少个版本的类,为什么您希望运行这些版本而不是无限数量?例如,
CGenericPassive<int> CGenericActive<int>::ms_passive;和CGenericPassive<char***> CGenericActive<char***>::ms_passive;您所说的“从类中消除静态”是什么意思? -
有什么问题?这段代码没有按照你的想法做吗?这个代码输出什么?更具体地说,这段代码在做什么,你需要调整你的教育?
-
@Dan 模板化的静态成员必须在非模板化函数中显式引用才能被实例化,而普通静态不会。我得到了一个答案,指出了这一点,但感觉很老套,或者好像 c++ 的规则中有一个怪癖。
-
您还没有定义问题所在。有问题吗?为了记录,成员没有被实例化。班是。如果你不调用成员函数,那么就没有必要存在一个。如果您不专门化模板,则不需要存在该模板专门化。但是实例化代码必须在创建类实例时生成。
-
我确实已经定义了问题是什么(但是问题很长并且充满了示例代码,因此乍一看可能很无聊和混乱)。简而言之:为什么只为非模板类创建/构造该静态成员,而不是为模板类创建/构造,即使创建了此容器类类型的对象?这个成员将被编译器丢弃并不是很明显(编译器遵循什么规则:丢弃非直接使用的模板代码?)。谢谢!
标签: c++ templates visual-c++ static generic-programming