首页 > 解决方案 > С调用带有字符串变量的静态类结构而没有c ++中的对象

问题描述

需要以代码中描述的格式接收数据,但问题在于字符串变量的操作。可以做些什么来避免错误?

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";
                                   ^~~~~~

来源 github.com

标签: c++static

解决方案


免责声明:

我的第一印象是这段代码滥用classstruct实际namespace发明的目的。

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


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

#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";
      |                                       ^~~~~~

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

coliru 现场演示

笔记:

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

进一步阅读:

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

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

coliru 现场演示

笔记:

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


推荐阅读