为什么我的编译器显示有关我的 constexpr 函数的此错误?

Why does my compiler show this error about my constexpr function?

本文关键字:我的 函数 错误 编译器 显示 为什么 constexpr      更新时间:2023-10-16

晚上好,

我必须实现一个带有 constexpr 函数的类,该函数在头文件中返回一个类成员。该成员是 const 并在我的构造函数中设置,因此它稍后不会在程序中更改。

头文件实现:

//Creates a PreAllocString object
#define CREATE (varName,size) {
char string##varName##[size] {''};
PreAllocString varName (string##varName##, size);
}
class PreAllocString 
{
private:
char* string;
const std::size_t size;
std::size_t length = 0;
operator const char *() const;
operator const void *() const;
const char & operator [] (const int idx);
public:
//Constructor
PreAllocString (char* string, const std::size_t size);
.
.
.

CPP文件实现:

#include "PreAllocString.h"
//Constructor
PreAllocString::PreAllocString (char* string, const std::size_t size) : string(string), size(size) {
if (string != nullptr) {
this->Empty();
}
}
.
.
.

我的编译器总是显示:

In file included from src/PreAllocString.cpp:2:0:
include/PreAllocString.h:30:27: error: enclosing class of constexpr non-static member function ‘std::size_t PreAllocString::SizeOf()’ is not a literal type
constexpr std::size_t SizeOf () {
^
include/PreAllocString.h:11:7: note: ‘PreAllocString’ is not literal because:
class PreAllocString 
^
include/PreAllocString.h:11:7: note:   ‘PreAllocString’ is not an aggregate, does not have a trivial default constructor, and has no constexpr constructor that is not a copy or move constructor

我做错了什么?

这里的C家伙...我真的不能帮你写惯用C++,但我可以试着解释为什么我能发现的一些事情是错误的。


#define CREATE (varName,size) {  
... 
}

这可能不会达到您的预期。 我假设您正在尝试定义一个类似函数的宏,该宏可扩展以声明数组和 PreAllocString 实例,因此像CREATE(somename,somesize)声明对象一样调用它?
㞖。。。

  • 宏名称及其参数列表之间不能有空格。 如果有空间,那么接下来的任何内容都是扩展的一部分。 例如:
    #define WORKS(varName) int varName
    #define DOESNT (varName) int varName
    WORKS(i);>>int i;
    DOESNT(i);>>(varName) int varName(i);

  • 主体周围的大括号不是宏定义的语法,将它们放在那里意味着它们出现在扩展中。 即:
    CREATE(aName,6)...
    >>{ char stringaName[6] {''}; //technically no line break PreAllocString aName (stringaName, 6); }

  • 除非你展示的代码不完整,或者我根本不了解类构造函数......构造函数的实现不应该调用这个东西吗?


#define CREATE (varName,size) {
char string##varName##[size] {''};
PreAllocString varName (string##varName##, size);
}

varName##[大小]...
varName##,大小...


这似乎没有表现出错误(目前...),但这不是令牌粘贴运算符的合法使用,您在这里得到的是未定义的行为。
https://en.cppreference.com/w/cpp/preprocessor/replace
令牌粘贴尝试将两个相邻的预处理器令牌合并为一个新的令牌...并且[/,("标点符号")不能成为标识符令牌的一部分。(撇开意图不谈,由于其他令牌粘贴指令:p,这是varName唯一有效的扩展)这个案件发生的结果似乎是...无。 您可以删除这些指令;串联失败后,未更改的单独令牌只是单独摄取,就好像什么都没发生一样。 不过,这种结果本质上是愚蠢的运气。