簡體   English   中英

C++ string.length() 不能在常量表達式中使用

[英]C++ string.length() not usable in a constant expression

使用 C++。 我有以下一段代碼,我試圖使用模板將二維數組的大小傳遞給函數 foo。 然而問題是傳遞給模板的大小必須是恆定的。 任何指針都有幫助,謝謝。

#include <iostream>
using namespace std;

template <size_t r, size_t c>
bool foo(bool (&arr)[r][c])
{
    cout << "foo\n";
}

int main() {
    string s = "abcd";
    const size_t N = s.length(); //is this incorrect?
    bool arr[N][N];
    foo<N, N>(arr);
    return 0;
}

似乎 string.length() 或 string.size() 不能用於初始化常量。 當我嘗試編譯時出現錯誤:

main.cpp: In function ‘int main()’:
main.cpp:14:6: error: the value of ‘N’ is not usable in a constant expression
  foo<N, N>(arr);
      ^
main.cpp:12:15: note: ‘N’ was not initialized with a constant expression
  const size_t N = s.length();
               ^
main.cpp:14:9: error: the value of ‘N’ is not usable in a constant expression
  foo<N, N>(arr);
         ^
main.cpp:12:15: note: ‘N’ was not initialized with a constant expression
  const size_t N = s.length();
               ^
main.cpp:14:15: error: no matching function for call to ‘foo<N, N>(bool [N][N])’
  foo<N, N>(arr);
               ^
main.cpp:5:6: note: candidate: template<long unsigned int r, long unsigned int c> bool foo(bool (&)[r][c])
 bool foo(bool (&arr)[r][c])
      ^~~
main.cpp:5:6: note:   template argument deduction/substitution failed:
main.cpp:14:15: error: the value of ‘N’ is not usable in a constant expression
  foo<N, N>(arr);
               ^
main.cpp:12:15: note: ‘N’ was not initialized with a constant expression
  const size_t N = s.length();
               ^
main.cpp:14:15: note: in template argument for type ‘long unsigned int’ 
  foo<N, N>(arr);
               ^
main.cpp:14:15: error: the value of ‘N’ is not usable in a constant expression
main.cpp:12:15: note: ‘N’ was not initialized with a constant expression
  const size_t N = s.length();
               ^
main.cpp:14:15: note: in template argument for type ‘long unsigned int’ 
  foo<N, N>(arr);
           ^
 const size_t N = s.length(); //is this incorrect? 

它結構良好,具有明確的行為。

似乎string.length()或string.size()不能用於初始化常量。

當然可以。 它可用於初始化運行時常量變量,這就是你的N

但它不能用於初始化編譯時常量。 您在需要編譯時常量表達式的上下文中使用運行時常量變量。

一個簡單的修復:使用字符串文字的大小:

// could use constexpr too
const unsigned long N = std::size("abcd") - 1;

注意-1來說明空終止符。

術語“常量表達”可能有點令人困惑。 它實際上意味着在編譯時已知的東西。 它與const

您可能想要查看string_view類。 https://en.cppreference.com/w/cpp/string/basic_string_view

它是一個非擁有的文本視圖,可以引用string ,字符串文字和其他幾個東西。

在您的情況下,由於您使用的是字符串文字,因此可以使用string_view作為string替換。

這不行。

盡管在這種特殊情況下你的字符串是從文字初始化的,但std::string長度是“動態”,所以std::string::length()永遠不會是常量表達式。 它永遠不能用作模板參數,因為在實例化模板時,編譯時不會(通常)再次知道該值。

請記住, const不會自動使某些東西成為常量表達式; 盡管它的名字,它並沒有真正創造一個“常量”,只是一個變量的名稱,通過它你不能改變該變量(初始化后)。

這些天我們可以使用constexpr標記“真實”常量,當你嘗試使用不適合賬單的東西時,你將獲得更好的診斷...例如std::string::length()

(但是可以在沒有constexpr情況下創建一些常量表達式;例如,文字是常量表達式,一些static const事物的名稱也是如此。)

你將不得不依靠bool的向量(但要小心!這些很奇怪......)或用其他東西替換你的字符串(比如字符數組,你的文字已經是......)。

任何指針都有幫助

出於同樣的原因,指針在這里也無濟於事。 ;)

我建議你使用c.size(); 而不是c.length();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM