首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >关于基类中的显式模板实例化和静态变量:编译器错误还是规范的有效解释?

关于基类中的显式模板实例化和静态变量:编译器错误还是规范的有效解释?
EN

Stack Overflow用户
提问于 2011-09-04 08:35:33
回答 1查看 715关注 0票数 1

据我的理解(C++公共知识,项目61;Solaris Studio C++用户指南),一个模板类的显式实例化将导致它的所有成员被实例化。但是,我发现Solaris Studio C++编译器的情况并非如此。由于此编译器的行为通常与其他编译器非常不同,同时仍然遵循规范(通常在更严格的意义上),因此我向任何C++模板专家询问我所看到的行为是否有效。

我的情况是,我有一个模板类“派生”,它继承自一个模板类"Base“专门用于”派生“。"Base“包含一个静态变量"tracer”,它必须在编译后出现在对象文件中(在我的完整代码中,这与向工厂注册“派生”有关)。大多数编译器(GCC、Open64、Intel、Clang、Visual C++)都是这样的。但是,在Solaris Studio中,只有当“派生”的构造函数在其定义中没有实现时才会发生这种情况,否则,"tracer“不会放在对象文件中(并且”派生“不会在Factory中注册)。

下面是一些简单的代码来演示这个问题:

Base.h:

代码语言:javascript
运行
复制
#ifndef BASE_H_
#define BASE_H_
template<typename T>
class Base {
 public:
  Base() : dummy_(g_tracer_) { }
 private:
  bool dummy_;
  static bool g_tracer_;
};

template<typename T>
bool Base<T>::g_tracer_ = true;
#endif  // BASE_H_

DerivedA.cc:

代码语言:javascript
运行
复制
#include "Base.h"
template<typename T>
class DerivedA : private Base<DerivedA<T> > {
 public:
  DerivedA(int val);
  T GetVar() const;
 private:
  T var_;
};

template<typename T>
DerivedA<T>::DerivedA(const int val) : var_(val) { }

template<typename T>
T DerivedA<T>::GetVar() const { return var_; }

// Explicit Instantiation
template class DerivedA<double>;

DerivedB.cc:

代码语言:javascript
运行
复制
#include "Base.h"
template<typename T>
class DerivedB : private Base<DerivedB<T> > {
 public:
  DerivedB(int val) : var_(val) { }
  T GetVar() const;
 private:
  T var_;
};

template<typename T>
T DerivedB<T>::GetVar() const { return var_; }

// Explicit Instantiation
template class DerivedB<double>;

如果我用sunCC -c编译“sunCC -c”文件,并对结果的对象文件运行nm,“德里维达A.o”包含"g_tracer_“(0000000000000000 V __1cEBase4nIDerivedA4Cd___Jg_tracer__)的符号,但”德里维德B.o“不包含”g_tracer_“符号。(注意:即使我使用-template=wholeclass选项,输出中仍然不存在符号。)使用任何其他编译器,两个目标文件都将包含一个与"g_tracer_“相对应的符号。

这是有效的行为,还是一个晦涩的编译器错误?我对C++规范的了解并不足以让我相信这两种方式。(实际上,我在这里看到了一个答案,表明显式实例化可能不会实例化基类成员,所以现在我特别困惑。)如对此事有任何澄清,我将不胜感激。谢谢!

EN

回答 1

Stack Overflow用户

发布于 2011-09-04 11:21:51

嗯,您是否真的尝试过设置一个使用实例化类的程序?因为您只是创建一个“库”(这是标准根本不谈论的事情),我相信编译器(或者更好的是图书管理员)可以做它想做的任何事情。试着建立一个把所有东西连接在一起的程序。我假设,如果没有一些关于未使用符号实例化的特定链接器配置,或者没有一些强制使用的诡计,那么最终您将完全没有g_tracers的实例化--链接器将根本不会将它们添加到程序中。

干杯,

保罗

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7298116

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档