c++ - 在 C++ 中使用没有对象的字符串变量调用静态类结构

标签 c++ static

需要按照代码描述的格式接收数据,但是问题出在字符串变量的操作上。如何避免错误?

class Class1
{
public:
    Class1() = delete ;
    const static int x = 1;
    static struct ZZ {
        const static int z1 = 1;
        const static QString z2 = "word";
    } z;
};

int main(int argc, char* argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << Class1::z.z2;
    return a.exec();
}

错误:

class1.h:13: ошибка: in-class initialization of static data member 'const QString Class1::ZZ::z2' of non-literal type
         const static QString z2 = "word";
                              ^~
class1.h:13: ошибка: call to non-constexpr function 'QString::QString(const char*)'
         const static QString z2 = "word";
                                   ^~~~~~

Source github.com

最佳答案

免责声明:

我的第一印象是这段代码滥用了 classstructnamespace 实际上是为了什么而发明的。

也就是说,答案集中在 OP 代码中 static 数据成员的技术问题上。


为了重现这个问题,我做了以下类似的例子:

#include <iostream>
#include <string>

class Class1
{
public:
    Class1() = delete ;
    const static int x = 1;
    static struct ZZ {
        static const int z1 = 1;
        static const std::string z2 = "word";
    } z;
};

int main(int argc, char* argv[])
{
    std::cout << Class1::z.z2;
}

输出:

main.cpp:11:34: error: in-class initialization of static data member 'const string Class1::ZZ::z2' of non-literal type
   11 |         static const std::string z2 = "word";
      |                                  ^~
main.cpp:11:39: error: temporary of non-literal type 'const string' {aka 'const std::__cxx11::basic_string<char>'} in a constant expression
   11 |         static const std::string z2 = "word";
      |                                       ^~~~~~

Live Demo on coliru

恕我直言,这已经足够接近 OP 的问题了。

TL;DR:问题是 static 成员变量必须显式定义(非内联)或标记为 inline

所以,我的修复看起来像这样:

#include <iostream>
#include <string>

class Class1
{
public:
    Class1() = delete ;
    const static int x = 1;
    inline static struct ZZ {
        static const int z1 = 1;
        inline static const std::string z2 = "word";
    } z = ZZ{};
};

int main(int argc, char* argv[])
{
    std::cout << Class1::x << '\n'
      << Class1::z.z1 << '\n'
      << Class1::z.z2 << '\n';
}

输出:

1
1
word

Live Demo on coliru

注意:

虽然 inline 对于 struct ZZstd::string 是必需的,但对于整数类型可以省略。因此,static const int z1 = 1; 将被无怨无悔地接受(没有前缀 inline)。

进一步阅读:

Static data members在 cppreference.com 上


为了比较,同样的代码在没有 inline 的情况下也能工作:

#include <iostream>
#include <string>

class Class1
{
public:
    Class1() = delete ;
    const static int x = 1;
    static struct ZZ {
        static const int z1 = 1;
        static const std::string z2;
    } z;
};

//Class1::ZZ Class1::z;
const std::string Class1::ZZ::z2 = "word";

int main(int argc, char* argv[])
{
    std::cout << Class1::x << '\n'
      << Class1::z.z1 << '\n'
      << Class1::z.z2 << '\n';
}

输出:

1
1
word

Live Demo on coliru

注意:

关于 const Class1::ZZ Class1::z;,我不是很确定。缺少的定义可能会被遗漏,因为 Class1::z 本身从未被使用过。

为了检查这一点,我再次修改了样本:

#include <iostream>
#include <string>

class Class1
{
public:
    Class1() = delete ;
    const static int x = 1;
    static struct ZZ {
        static const int z1 = 1;
        static const std::string z2;
    } z;
};

Class1::ZZ Class1::z;
const std::string Class1::ZZ::z2 = "word";

std::ostream& operator << (std::ostream &out, const Class1::ZZ &z)
{
  return out << z.z1 << ", " << z.z2;
}

int main(int argc, char* argv[])
{
    std::cout << Class1::x << '\n'
      << Class1::z << '\n'
      << Class1::z.z1 << '\n'
      << Class1::z.z2 << '\n';
}

输出:

1
1, word
1
word

Live Demo on coliru

注意:

注释 Class1::z 的定义(就像在前面的示例中一样)会导致链接错误。

关于c++ - 在 C++ 中使用没有对象的字符串变量调用静态类结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58899005/

相关文章:

c++ - C++ 类成员的替代实现语法

c++ - 出现频率

c++ - 使用protobuf进行线程通信

java - final 以某种方式导致静态行为

c - 在 C 本地范围内使用 static 关键字来运行

c++ - 了解指针引用的工作原理

c++ - gcov 忽略源文件中的行

Java 静态自引用

c - 使用 static 关键字声明变量

C++ map<char, static method pointer>?