我不明白为什么如果我全局初始化这个模板变量,如下所示:
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;它可以工作,但是如果我试图在类中初始化它,如下所示:
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;
};它给了我一个错误:
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;
| 你知道为什么吗?
发布于 2022-07-25 13:47:27
添加缺少的static。然后,要么将变量定义移动到命名空间范围:
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;或者让他们在网上:
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;
};发布于 2022-07-25 14:00:32
问题是在类范围中为静态数据成员提供定义,而不是当静态数据成员的定义必须放在包含成员类定义的名称空间范围中时,而不是命名空间范围。从class.static.data#3中可以看出这一点,它声明:
类定义中的非内联静态数据成员的声明不是定义,并且可能是cv以外的不完整类型。未在类定义中内联定义的静态数据成员的定义应出现在包含成员类定义的命名空间范围中。在名称空间范围的定义中,静态数据成员的名称应使用::运算符由其类名限定。
(强调地雷)
因此,做您想做的事情的正确方法如下所示:
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为静态数据成员提供类内定义。
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
};https://stackoverflow.com/questions/73110191
复制相似问题