2017-12-29 6 views
4

std::vector<int> bフィールドのクラスをコンストラクタ内にコンストラクタで両方のコンテナに等しいサイズにしたいとします。私が理解から - - reserve()は完全に安全であると、size_typeパラメータを受け入れることを考えると、私が持っている、特にアピールされていない2つのパラメータを使用して私のコンストラクタ、書き込み:私は何を読んでから、コンテナ<T> :: size_typeをさまざまなタイプTに普遍的に使用する方法はありますか?

MyCtor(std::vector<bool>::size_type size1, std::vector<int>::size_type size2) 
{ 
    abortIfNotEqual(size1, size2); // Proceed only if size1 == size2 
    a.reserve(size1); 
    b.reserve(size2); 
} 

を、size_typeですは通常size_tと同じ、少なくとも標準コンテナのために、私はおそらく今まで潜在的な問題に遭遇することなくこれを行うことができます:

MyCtor(std::size_t size) 
{ 
    a.reserve(size); // More readable, but is this always ok? 
    b.reserve(size); 
} 

をしかし、厳密にsize_typeを使用するより良い、より安全な方法があります特定のタイプTの特定のcontainer<T>でアクセスする必要はありませんか?

具体的なcontainer<T>を使用することは、例えば、要素へのアクセス:a[i]istd::vector<bool>::size_typeでなければなりません。 unsigned int iは安全性が低くなります。

このような状況では、一般的で普遍的な読みやすい方法がありますか?または、私は単にsize_tまたはunsigned long intを使用してこれを忘れてしまってはいけませんか?

+0

私はそれがないと知っていますしかし、あなたは 'std :: int64_t'を使うこともできますし、両方を使うこともできます。関数を呼び出すときに偶然に負の値を生成した人はいません。著名な委員からの同様のアドバイスを聞きたい場合: https://channel9.msdn.com/Events/GoingNative/2013/Interactive-Panel-Ask-Us-Anything 9:50、42:40、1:02: 50 –

+1

Btw、あなたの質問への直接的な答えはおそらく 'std :: common_type'でしょうが、やはりそれは過度だと思います。 –

+4

'std :: size_t'は、割り当てられたメモリの最大サイズを表現するのに十分な大きさでなければならず、ベクトル内のすべてのオブジェクトのサイズが1より大きいため、' std :: size_t'は任意のベクトルのサイズを表すことができます。 – Oliv

答えて

3

あなたの質問の主な要素は、サイズの種類が同じであることを前提としてどう安全性を確保するかということなので、static_assert std :: is_sameをお勧めします。これはC++でコンパイルされます。17:

表記を簡略化することが重要でしたので、ここでは、このクラスにsize_typeをtypedefし、内部的にそれが表す両方のサイズの型と同じであることを確認します。一致しない場合、コンパイル時エラーです。 How to check if two types are same at compiletime(bonus points if it works with Boost strong typedef)また、C++ 11の回避策が含まれています。このスタックオーバーフローの答えに

#include <vector> 

class MyCtor { 
    std::vector<bool> a; 
    std::vector<int> b; 
    typedef std::vector<bool>::size_type st1; 
    typedef std::vector<int>::size_type st2; 
    static_assert(std::is_same<st1, st2>::value); 
public: 
    typedef st2 size_type; 
    MyCtor(size_type s1, size_type s2) {} 
}; 

感謝します。

1

私は、この2つのタイプのうち小さい方を受け入れる機能を持っています。 C++ 11では、これを介して行うことができます。

C++ 11を欠く
#include <vector> 
#include <type_traits> 
#include <limits> 

typedef std::vector<bool>::size_type boolType; 
typedef std::vector<int>::size_type intType; 

typedef std::conditional<(std::numeric_limits<boolType>::max() < 
          std::numeric_limits<intType>::max()), 
         boolType, 
         intType>::type smallerSizeType; 

MyCtor(smallerSizeType size) 
{...} 

、手動std::conditionalの独自のバージョンを定義し、static_cast<boolType>(-1)、などとstd::numeric_limits<boolType>::max()を置き換えることができます。..

+0

また、2つのタイプのうち_larger_を受け入れてから、オーバーフロー( 'reserve'を呼び出す前に)_inside_関数をチェックすることができます。これにより、オーバーフローのチェックでは、呼び出し元の関数ではなく関数の責任が発生します。 –

+0

(_larger_型を取得するには 'std :: common_type'で十分です) –

関連する問題