簡體   English   中英

將整數文字初始化為 std::size_t

[英]Initialize integer literal to std::size_t

有已知的方法來操作整數文字的類型

0L;  // long
3U;  // unsigned integer
1LL; // long long

我需要的是一種將整數文字初始化為std::size_t 我以為這樣做

2U; // unsigned int

就足夠了,但是在調用需要相同整數類型的兩個參數的函數模板時,我仍然遇到編譯器錯誤(沒有匹配的函數來調用func(unsigned int, size_t

我知道/驗證顯式轉換( static_cast<std::size_t>(1) )第一個參數解決了問題,但我問是否有更漂亮的解決方案

編輯

該函數有一個簽名

template <class T> const T& func(const T& a, const T& b);

編輯2

我不知道這個問題是否是“責備”,但我很高興地宣布即將推出(cudos @malat 在評論中提到了這一點)

沒有這樣的標准設施。 C99 和 C++11 實現在<stdint.h> / <cstdint>有這樣的宏。 但即使在那里,宏也只為stdint.h類型定義,不包括size_t

可以定義用戶定義的文字運算符:

constexpr std::size_t operator "" _z ( unsigned long long n )
    { return n; }

auto sz = 5_z;
static_assert( std::is_same< decltype( sz ), std::size_t >::value, "" );

在數組邊界int arr[ 23_z ]case 9_z:標簽中使用constexpr是必要的。

大多數人可能會認為沒有宏是一個優勢:)。


除了可愛之外,最好的方法是使用大括號初始化: std::size_t{ 42 } 這不等同於std::size_t( 42 ) ,它就像一個討厭的 C 類型轉換——大概是你用static_cast避免的。 恰恰相反:大括號要求內部的值在目標類型中完全可以表示。 所以, char{ 300 }std::size_t{ -1 }都是病態的。

大括號和括號看起來很相似,但在初始化臨時變量時,它們在安全性上是截然相反的。 大括號比文字運算符更安全,因為與函數不同,它們可以區分編譯時值。

std::size_t沒有專門的后綴。 在 C++11 中,你可以為它創建一個用戶定義的文字,但是:

std::size_t operator "" _sz (unsigned long long int x)
{
  return x;
}

// Usage:

auto s = 1024_sz;

static_assert(std::is_same<decltype(s), std::size_t>::value, "He's wrong");

活生生的例子

從 C++23 開始,您可以將uzUZ文字用於size_t

auto size = 42uz;
static_assert(std::is_same_v<decltype(size), std::size_t>);

紙: P0330R8
cppreference:整數文字

根據功能,您也可以這樣做,並且可能會發現它更干凈:

auto result = func<size_t>(1, some_var);

例如,我用std::max做到了這一點:

auto result = std::max<size_t>(0, std::min<size_t>(index, vec.size()-1));

通過顯式指定模板實例化,轉換可以是隱式的。 但是,請注意,這是一個強制轉換,因此容易出現Potatoswatter 的大括號初始化所沒有的錯誤。

暫無
暫無

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

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