我试图用字符串:: size成员创建一个数组,但它在" char message [msgSize]"的声明中抱怨表达式没有评估常量。
然而它让我宣布" msgSize"。
这怎么可能?为什么我被允许做一个常数,但我不允许将它用于需要const的东西。
如果答案是:"字符串的大小可能会改变"然后可以使用sizeof()进行相同的参数,但这样可行。
const unsigned int msgSize =
saveAs.size() +
sizeof("NOTE| sent get request to: ") + 10;
char message[msgSize];
memset(message, 0, msgSize);
sprintf_s(message, msgSize,"NOTE| sent get request to: %s", saveAs.c_str());
_cRec->output(message);
答案 0 :(得分:1)
好const
只是意味着你保证价值不会改变。您甚至可以使用const_cast
覆盖它。
编译器需要什么,可以在编译时评估一个值。这是一个更强烈的要求。此类值标有constexpr
关键字。
不幸的是,std::string
让你感到不快...... size()
不是constexpr
。
#include <iostream>
#include <string>
using namespace std;
const string msg("Some msg");
constexpr int msg_len = msg.size();
int main() {
char msg[msg_len];
cout << sizeof(msg);
return 0;
}
问题是size()
不是constexpr
,你不能使string
成为constexpr
,因为它有一个非平凡的析构函数。
为什么这样设计是超出我的。似乎是反直觉和严重的限制。但是,有string
的非常聪明的实现,例如小存储优化。可能很难让他们constexpr
在实施中发生严重变化。
答案 1 :(得分:0)
您必须使您的阵列动态化。 compile 时不知道字符串的大小,但仅在运行时。
此外,您的商家信息不是最小的可编辑示例。我只能假设saveAs
是一个std :: string。
以下方法可行:
int main()
{
std::string myString("My string");
char * myCStyleString = new char[myString.size()];
delete[] myCStyleString;
}
因为我们动态地在那里分配一个数组。
你想做什么?看起来您只想将文件名复制到消息字符串中。继续使用std :: string;
int main()
{
std::string myString("My string");
std::string message = "I like beans and rice with: ";
message += myString;
return 0;
}
但同样,我需要一个最小的可编辑示例来确定您的目标。
答案 2 :(得分:0)
为什么我可以保持常数,但我不允许使用它 需要const的东西。
这是因为&#34;常数&#34;您拥有的表达式由非常量部分组成,即字符串类的大小方法。就编译时具有已知值而言,它并不是真正的常量。
考虑将来使用constexpr
变量/函数
如果答案是:&#34;字符串的大小可能会改变&#34;那么 可以使用sizeof()进行相同的参数,但是可行。
不能将相同的参数用于sizeof,因为sizeof不需要它作为常量。
如果您知道saveAs
包含已知大小的字符串这一事实,那么最好将该大小声明为常量然后在计算中引用它:
constexpr unsigned int msgSize =
SAVEAS_SIZE +
sizeof("NOTE| sent get request to: ") + 10;
然后这将允许你这样做:
char message[msgSize];
答案 3 :(得分:0)
在C ++中,您无法声明VLA s。
声明数组时,例如:
char message[x];
表达式x
必须在compile time处有价值,因为在编译源代码时,它的值必须是众所周知的。
在你的例子中:
char message[msgSize];
表达式(变量)msgSize
在编译时是未知的,但仅在运行时。那是因为编译器必须知道堆栈中保留了多少字节。
注意:变量msgSize
是常量值。常量值不表达式在编译时计算。它只是意味着一旦分配了它的值就不会改变。
在C ++ 11中引入了关键字constexpr
,以便定义一个应该在编译时进行评估的表达式。
但是在您的情况下,无法在编译时获取动态字符串的大小。所以你要做的就是使用动态数组(动态内存)。
char* message = new char[msgSize];
// now you have an array of msgSize lenght
// ... do stuff...
// do not forget to release the memory when end
delete[] message;
最后,我建议你重新详细说明你的代码,因为你可能不需要动态的字符数组,只需要std::string
。实际上,您可以使用重载的运算符+
来连接字符串,并使用方法std::string::c_str()
来访问const char*
以实现向后兼容性。
答案 4 :(得分:0)
你需要一个带有char message[msgSize];
的编译时常量,因为这是一个局部变量,它使用在数据段中分配的静态内存,所以编译器需要计算代码所需的字节数,包括局部变量和数组。
您可以使用动态内存来解决问题。 动态内存在堆中分配。在C中,您应该使用malloc()
。在C ++中,您应该使用new[]
(或更好,std::vector
,甚至std::string
)。然后,您可以使用变量中的运行时值指定内存大小。
因此,您的代码看起来更像是以下内容:
char* message = new char[msgSize]; //Allocated memory
//Do everything that you need...
delete[] message; //Release memory
或者:
#include <vector>
std::vector<char> message(msgSize); //Allocated memory
//Do everything that you need...