String.length困扰

时间:2016-03-21 16:40:47

标签: c++ loops constants string-length

编辑:解决方案必须针对Microsoft Visual Studio 2012进行编译。

我想使用已知的字符串长度来声明另一个长度相同的字符串。

推理是第二个字符串将充当对第一个字符串进行操作的容器,该字符串必须是非易失性的。

e.g。

const string messy "a bunch of letters";

string dostuff(string sentence) {
    string organised NNN?????  // Idk, just needs the same size.
    for ( x = 0; x < NNN?; x++) {
        organised[x] = sentence[x]++; // Doesn't matter what this does.
    }
}

在上述两种情况下,声明和退出条件,NNN?代表“凌乱”的长度。

如何在编译时发现长度?

2 个答案:

答案 0 :(得分:2)

std::string有两个constructors符合您的目的。

第一个是复制构造函数:

string organised(sentence);

第二个,一个带字符和计数的构造函数。您可以使用临时字符初始化字符串。

string organised(sentence.length(), '_'); 

或者,您可以:

  • 使用空字符串并随身携带(+=)文字,或
  • 出于同样目的使用std::stringstream

stringstream可能会更有效率。

总的来说,如果长度已知,我更喜欢复制构造函数。

答案 1 :(得分:1)

CREATE VIEW [dbo].[vw_FilesNotYetLoaded] AS SELECT lf.ID, filename, filetype FROM JPStarter.dbo.LoadedFiles lf JOIN JPStarter.staging.ExitPages AS ep ON lf.ID = ep.LoadedFile_id JOIN JPStarter.staging.LandingPages AS lp ON lf.ID = lp.LoadedFile_id WHERE lf.ID NOT IN ( SELECT ID FROM JPStarter.dbo.LoadedFiles ) 不是编译时类型(它不能是std::string),所以你不能直接用它来确定编译时的长度。

您可以初始化constexpr constexpr,然后使用char[]

sizeof

并使用它,但坦率地说,这非常难看;长度是编译时间,但是constexpr char messychar[] = "a bunch of letters"; // - 1 to avoid including NUL terminator which std::string doesn't care about constexpr size_t messylen = sizeof(messychar) / sizeof(messychar[0]) - 1; const string messy(messychar); 需要使用仍然会在每次调用时执行的organizedcount构造函数,仅分配和初始化以在循环。

虽然不是编译时间,但只需使用charreserve来构建新的+=即可避免初始化成本,string可以使用#define以丑陋但可能有效的方式完成:

constexpr char messychar[] = "a bunch of letters";
constexpr size_t messylen = sizeof(messychar) / sizeof(messychar[0]) - 1;
// messy itself may not be needed, but if it is, it's initialized optimally
// by using the compile time calculated length, so there is no need to scan for
// NUL terminators, and it can reserve the necessary space in the initial alloc
const string messy(messychar, messylen);

string dostuff(string sentence) {
    string organised;
    organized.reserve(messylen);
    for (size_t x = 0; x < messylen; x++) {
        organised += sentence[x]++; // Doesn't matter what this does.
    }
}

这可以避免多次设置organised的值,每次调用多次分配(好吧,如果初始构造执行它可能两次),并且只执行{{1}的单个读/写传递},没有完整的读取,然后是读/写等。它还使循环约束成为编译时的值,因此编译器有机会展开循环(虽然不能保证这一点,即使它发生了,也可能没有用)。

另请注意:在您的示例中,您变异sentence,但它被值接受,因此您正在改变本地副本,而不是调用者副本。如果需要突变调用者值,则通过引用接受它,如果不需要突变,则通过sentence引用接受以避免每次调用都有一个副本(我知道示例代码是填充符,只是提到这一点)。