晚上好,
我必须使用constexpr函数实现一个类,该函数在头文件中返回一个类成员。该成员是const并在我的构造函数中设置,因此它不会在程序中稍后更改。
头文件实现:
//Creates a PreAllocString object
#define CREATE (varName,size) {\
char string##varName##[size] {'\0'};\
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] {'\0'}; //technically no line break
PreAllocString aName (stringaName, 6); }
#define CREATE (varName,size) {\
char string##varName##[size] {'\0'};\
PreAllocString varName (string##varName##, size);\
}
... varName
## [
size] ...
... varName
## ,
尺寸......
这似乎没有表现出错误(现在......),但这不是合法使用令牌粘贴操作符以及您在此处获得的是未定义的行为。
https://en.cppreference.com/w/cpp/preprocessor/replace
令牌粘贴尝试将两个相邻的预处理器令牌组合成一个新的...并且[
/ ,
('punctuators')不能成为标识符令牌的一部分。 (由于另一个标记粘贴指令,故意放在一边,是varName
的唯一有效扩展:p)这个案例的结果似乎是......没有。你可以删除那些指令;连接失败后,未更改的单独令牌就会被单独摄取,就好像什么也没发生一样。然而,结果本质上是愚蠢的运气。