首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法在类内初始化模板变量,为什么?

无法在类内初始化模板变量,为什么?
EN

Stack Overflow用户
提问于 2022-07-25 13:38:23
回答 2查看 79关注 0票数 1

我不明白为什么如果我全局初始化这个模板变量,如下所示:

代码语言:javascript
复制
template <class T> struct null_string { static const std::string value; };
template<class T> const std::string null_string<T>::value = "";
template<class T> std::string const null_str = null_string<const T&>::value;

它可以工作,但是如果我试图在类中初始化它,如下所示:

代码语言:javascript
复制
class foo
 {
  template <class T> struct null_string { static const std::string value; };
  template<class T> const std::string null_string<T>::value = "";
  template<class T> std::string const null_str = null_string<const T&>::value;
 };

它给了我一个错误:

代码语言:javascript
复制
prove.cpp:8:65: error: invalid use of qualified-name ‘foo::null_string<T>::value’
    8 |     template<class T> const std::string null_string<T>::value = "";
      |                                                                 ^~
prove.cpp:11:78: error: data member ‘null_str’ cannot be a member template
   11 |   template<class T> std::string const null_str = null_string<const T&>::value;
      |  

你知道为什么吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-07-25 13:47:27

添加缺少的static。然后,要么将变量定义移动到命名空间范围:

代码语言:javascript
复制
class foo
{
    template <class T> struct null_string { static const std::string value; };
    template <class T> static std::string const null_str;
};

template <class T> const std::string foo::null_string<T>::value = "";
template <class T> std::string const foo::null_str = foo::null_string<const T&>::value;

或者让他们在网上:

代码语言:javascript
复制
class foo
{
    template <class T> struct null_string { inline static const std::string value = ""; };
    template <class T> inline static const std::string null_str = foo::null_string<const T&>::value;
};
票数 3
EN

Stack Overflow用户

发布于 2022-07-25 14:00:32

问题是在类范围中为静态数据成员提供定义,而不是当静态数据成员的定义必须放在包含成员类定义的名称空间范围中时,而不是命名空间范围。从class.static.data#3中可以看出这一点,它声明:

类定义中的非内联静态数据成员的声明不是定义,并且可能是cv以外的不完整类型。未在类定义中内联定义的静态数据成员的定义应出现在包含成员类定义的命名空间范围中。在名称空间范围的定义中,静态数据成员的名称应使用​::​运算符由其类名限定。

(强调地雷)

因此,做您想做的事情的正确方法如下所示:

代码语言:javascript
复制
class foo
 {
  template <class T> struct null_string 
  { 
      static const std::string value; //declaration not a definition
  };
//------------------vvvvvv---------------------------->added static here
  template<class T> static std::string const null_str;//declaration not a definition
 };

 //provide definition for static members at global scope
template<class T> const std::string foo::null_string<T>::value = "";
template<class T> std::string const foo::null_str = foo::null_string<const T&>::value;

演示

使用C++17,还可以使用inline为静态数据成员提供类内定义。

代码语言:javascript
复制
class foo
 {
  template <class T> struct null_string 
  { 
//----vvvvvv--------------------------------->  inline used here
      inline static const std::string value = "";    //definition
  };
//--------------------------vvvvvv--------------------------->added static here
  template<class T> inline static std::string const null_str = foo::null_string<const T&>::value;//definition
//------------------^^^^^^----------------------------------->inline used here
 };
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73110191

复制
相关文章

相似问题

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