このマクロに変換され、機能しているのでしょうか。
-
01-07-2019 - |
質問
なリファクタリングのコードと喜自分自身の#定義されている教嫌いないたようで、私はこの美しさの計算に使用する多数の要素構造:
#define STRUCTSIZE(s) (sizeof(s) / sizeof(*s))
として非常に有用でき換、インライン機能はテンプレート?
OK、ARRAYSIZE行動に移すべきなので名前はレガシーコード(うましたから、少なくとも15歳以上)で貼り付けで変更することがあります。
解決
として上記のコードを実際に仕事の要素数配列は、struct.私だけを書き出すたsizeof()部門を明示的に合います。またその機能、使いたいと思っていることを明確にするその定義で期待します。
template<typename T,int SIZE>
inline size_t array_size(const T (&array)[SIZE])
{
return SIZE;
}
上記と類似 xtoflの, を除き、いを防ぐポインタをするという点を動的に割り当て配列)を間違った答えするものとします。
編集:簡略化して JohnMcG. 編集:インライン.
残念ながら、上記によって提供されていないコンパイル時に答えであってもコンパイラはインライン&最適化できる定数の下にフード)で使用できないとしてコンパイル時間を一定に発現する。すなわちとして使用することはできませんのサイズを宣言するのに静的な配列になります。の下でのC++0xでは、この問題を離れる場合に置き換えキーワード インライン による constexpr (constexprはインラインが暗黙的に).
constexpr size_t array_size(const T (&array)[SIZE])
jwfearnの 解作業のためのコンパイルが含有すtypedefる効果的に"保存"配列のサイズを宣言することができます。配列のサイズは、その手によinitialisingを一定による新しい名前です。この場合、一つのものだけを保存配列のサイズに定数からをしていきたいと思っています。
マーティンニューヨークの 掲載ソリューションに以下のコンパイル時間がな利用の基準 typeof() オペレーター作品の周辺には待機のためのC++0x用 decltype 時の一つなんでこの問題としてい constexpr).他のインタビューを受けたことがある利用が進みました。Typeofまだ終わ
#include <boost/typeof/typeof.hpp>
template<typename T>
struct ArraySize
{
private: static T x;
public: enum { size = sizeof(T)/sizeof(*x)};
};
template<typename T>
struct ArraySize<T*> {};
を使うことにより文書
ArraySize<BOOST_TYPEOF(foo)>::size
場所 foo の名前の配列になります。
他のヒント
なしはこれまで提案したポータブル取得のサイズを配列した際、インスタンスの配列としていると考えられているタイプです。(typeofと_countofは携帯でご利用いただけません)
思いので、以下の方法:
template<int n>
struct char_array_wrapper{
char result[n];
};
template<typename T, int s>
char_array_wrapper<s> the_type_of_the_variable_is_not_an_array(const T (&array)[s]){
}
#define ARRAYSIZE_OF_VAR(v) sizeof(the_type_of_the_variable_is_not_an_array(v).result)
#include <iostream>
using namespace std;
int main(){
int foo[42];
int*bar;
cout<<ARRAYSIZE_OF_VAR(foo)<<endl;
// cout<<ARRAYSIZE_OF_VAR(bar)<<endl; fails
}
- できるだけの価値はます。
- では、携帯型だけを使用しstd-C++.
- 失敗したとdescriptivエラーメッセージを表示します。
- ませんの評価値です。(思いつかないのがこの問題が配列型ではなまでに返送しなければならな機能が、より安全ですよ。)
- でサイズを返しましcompiletime定数です。
で包んだの構築へのマクロはとても構文です。いくのではないの置換になります。
KTC'sソリューションはクリーンで使用する事が出来ませんコンパイル時にも依存のコンパイラの最適化を防ぐコード-膨張、関数呼び出しオーバーヘッド。
計算が可能で配列サイズがコンパイル時のみmetafunctionゼロの実行時のコストです。 BCS したのがそのソリューションが間違っています。
ここでの私の解
// asize.hpp
template < typename T >
struct asize; // no implementation for all types...
template < typename T, size_t N >
struct asize< T[N] > { // ...except arrays
static const size_t val = N;
};
template< size_t N >
struct count_type { char val[N]; };
template< typename T, size_t N >
count_type< N > count( const T (&)[N] ) {}
#define ASIZE( a ) ( sizeof( count( a ).val ) )
#define ASIZET( A ) ( asize< A >::val )
テストコードを使用 が進みました。StaticAssert をコンパイル時のみ使用できます):
// asize_test.cpp
#include <boost/static_assert.hpp>
#include "asize.hpp"
#define OLD_ASIZE( a ) ( sizeof( a ) / sizeof( *a ) )
typedef char C;
typedef struct { int i; double d; } S;
typedef C A[42];
typedef S B[42];
typedef C * PA;
typedef S * PB;
int main() {
A a; B b; PA pa; PB pb;
BOOST_STATIC_ASSERT( ASIZET( A ) == 42 );
BOOST_STATIC_ASSERT( ASIZET( B ) == 42 );
BOOST_STATIC_ASSERT( ASIZET( A ) == OLD_ASIZE( a ) );
BOOST_STATIC_ASSERT( ASIZET( B ) == OLD_ASIZE( b ) );
BOOST_STATIC_ASSERT( ASIZE( a ) == OLD_ASIZE( a ) );
BOOST_STATIC_ASSERT( ASIZE( b ) == OLD_ASIZE( b ) );
BOOST_STATIC_ASSERT( OLD_ASIZE( pa ) != 42 ); // logic error: pointer accepted
BOOST_STATIC_ASSERT( OLD_ASIZE( pb ) != 42 ); // logic error: pointer accepted
// BOOST_STATIC_ASSERT( ASIZE( pa ) != 42 ); // compile error: pointer rejected
// BOOST_STATIC_ASSERT( ASIZE( pb ) != 42 ); // compile error: pointer rejected
return 0;
}
このソリューションは拒否する非配列型でコンパイル時間で取得しませんが混乱するポインタとしてのマクロ版です。
マクロは非常に誤解を招く名前の表現はマクロの戻りますの要素数配列が、配列名として渡されたマクロのパラメータとします。
その他の種類しょう以上の意味がない場合はタイプにポインタまたはい場合、構文エラーとなります。
通常、マクロの名前のようなものNUM_ELEMENTS()または何かを示すため、その真の有用性.することはできませんのマクロ機能にはC、C++テンプレートを使用できます。
の版を使っていベーコードマイクロソフトマイクロソフトのwinnt.hヘッダー(れば教えてください投稿このスニペットを超えた公正使用):
//
// Return the number of elements in a statically sized array.
// DWORD Buffer[100];
// RTL_NUMBER_OF(Buffer) == 100
// This is also popularly known as: NUMBER_OF, ARRSIZE, _countof, NELEM, etc.
//
#define RTL_NUMBER_OF_V1(A) (sizeof(A)/sizeof((A)[0]))
#if defined(__cplusplus) && \
!defined(MIDL_PASS) && \
!defined(RC_INVOKED) && \
!defined(_PREFAST_) && \
(_MSC_FULL_VER >= 13009466) && \
!defined(SORTPP_PASS)
//
// RtlpNumberOf is a function that takes a reference to an array of N Ts.
//
// typedef T array_of_T[N];
// typedef array_of_T &reference_to_array_of_T;
//
// RtlpNumberOf returns a pointer to an array of N chars.
// We could return a reference instead of a pointer but older compilers do not accept that.
//
// typedef char array_of_char[N];
// typedef array_of_char *pointer_to_array_of_char;
//
// sizeof(array_of_char) == N
// sizeof(*pointer_to_array_of_char) == N
//
// pointer_to_array_of_char RtlpNumberOf(reference_to_array_of_T);
//
// We never even call RtlpNumberOf, we just take the size of dereferencing its return type.
// We do not even implement RtlpNumberOf, we just decare it.
//
// Attempts to pass pointers instead of arrays to this macro result in compile time errors.
// That is the point.
//
extern "C++" // templates cannot be declared to have 'C' linkage
template <typename T, size_t N>
char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N];
#define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A)))
//
// This does not work with:
//
// void Foo()
// {
// struct { int x; } y[2];
// RTL_NUMBER_OF_V2(y); // illegal use of anonymous local type in template instantiation
// }
//
// You must instead do:
//
// struct Foo1 { int x; };
//
// void Foo()
// {
// Foo1 y[2];
// RTL_NUMBER_OF_V2(y); // ok
// }
//
// OR
//
// void Foo()
// {
// struct { int x; } y[2];
// RTL_NUMBER_OF_V1(y); // ok
// }
//
// OR
//
// void Foo()
// {
// struct { int x; } y[2];
// _ARRAYSIZE(y); // ok
// }
//
#else
#define RTL_NUMBER_OF_V2(A) RTL_NUMBER_OF_V1(A)
#endif
#ifdef ENABLE_RTL_NUMBER_OF_V2
#define RTL_NUMBER_OF(A) RTL_NUMBER_OF_V2(A)
#else
#define RTL_NUMBER_OF(A) RTL_NUMBER_OF_V1(A)
#endif
//
// ARRAYSIZE is more readable version of RTL_NUMBER_OF_V2, and uses
// it regardless of ENABLE_RTL_NUMBER_OF_V2
//
// _ARRAYSIZE is a version useful for anonymous types
//
#define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)
#define _ARRAYSIZE(A) RTL_NUMBER_OF_V1(A)
また、マシュー-ウィルソンの著書"不完全なC++"は素晴らし処理のうちセ14.3ページ211-213-配列とポインタ-dimensionof()).
おmacro misnamedで呼び出す必要があARRAYSIZE.かを決定するために使用される要素数配列対象のサイズがコンパイル固定。この方法での仕事:
char foo[128];//現実にはん ている定数は定数 表現として配列のサイズです。
のための(符号なしi=0;i <STRUCTSIZE( foo);++i){}
このような脆利用できること間違い:
char*foo=新しいchar[128];
のための(符号なしi=0;i <STRUCTSIZE( foo);++i){}
まに対して繰り返し処理を実行for i=0to < 1涙髪。
インターネットブラウザのテンプレート機能を推定を自動に対するテンプレートのクラスです。利用できるのでより簡単に:
template< typename T > size_t structsize( const T& t ) {
return sizeof( t ) / sizeof( *t );
}
int ints[] = { 1,2,3 };
assert( structsize( ints ) == 3 );
んに同意できない構造体:を動作させることができarrays.なされているのではないかと思い話でArraysize:)
Simplfying@KTCのためのサイズの配列がテンプレート引数:
template<typename T, int SIZE>
int arraySize(const T(&arr)[SIZE])
{
return SIZE;
}
うまコピーのことをバイナリー毎にTypename、サイズ組み合わせです。
- 関数は、テンプレート機能あり
- テンプレート"という質問に対し、思わないものC++
- テンプレートにとっては自分のもの)
編集: からはDougコード
template <typename T>
uint32_t StructSize() // This might get inlined to a constant at compile time
{
return sizeof(T)/sizeof(*T);
}
// or to get it at compile time for shure
class StructSize<typename T>
{
enum { result = sizeof(T)/sizeof(*T) };
}
と思っている2つの方法でやらねばならない。大藤のようなもので可能なだけでなC++のに十分で修理してください。
もしenum方法を提案する[BCS]( このマクロに変換され、機能しているのでしょうか。)
これを利用できるのでつかえば直通なので大変助かりのコンパイラを見込んでコンパイル時に定数です。現在のバージョンの言語せない機能が利用結果をコンパイル時にconstsると思いこと、その機能は次のバージョンのコンパイラ:
問題はこの方法はないものを生成するコンパイル時にエラーを使用した場合のクラスは、過負荷に'*'オペレータ参照コードの詳細は以下).
残念ながらの供給によるBCSは非常にコンパイルとして予定しているのでこちらが私のバージョン:
#include <iterator>
#include <algorithm>
#include <iostream>
template<typename T>
struct StructSize
{
private: static T x;
public: enum { size = sizeof(T)/sizeof(*x)};
};
template<typename T>
struct StructSize<T*>
{
/* Can only guarantee 1 item (maybe we should even disallow this situation) */
//public: enum { size = 1};
};
struct X
{
int operator *();
};
int main(int argc,char* argv[])
{
int data[] = {1,2,3,4,5,6,7,8};
int copy[ StructSize<typeof(data)>::size];
std::copy(&data[0],&data[StructSize<typeof(data)>::size],©[0]);
std::copy(©[0],©[StructSize<typeof(copy)>::size],std::ostream_iterator<int>(std::cout,","));
/*
* For extra points we should make the following cause the compiler to generate an error message */
X bad1;
X bad2[StructSize<typeof(bad1)>::size];
}
なかったと思うと本当にそうなの要素数になります。いた場合は、ご使用のものより小さいポインタサイズなどのchar32ビットシステム)以上の結果が間違っています。また、構造体を含む構造体お間違っています!
有できるテンプレートのC++
template <typename T>
size_t getTypeSize()
{
return sizeof(T)/sizeof(*T);
}
利用:
struct JibbaJabba
{
int int1;
float f;
};
int main()
{
cout << "sizeof JibbaJabba is " << getTypeSize<JibbaJabba>() << std::endl;
return 0;
}
見BCSのポストの上または下にて涼しくないというこのクラスはコンパイル時に用いテンプレートmetaprogramming.
xtoflの答えを見つける配列サイズです。ないマクロまたはテンプレートを必要とするためのサイズの構造体でsizeof()必要になります。
同意する プリプロセッサが悪, があるならではの 少なくとも悪の代替案について.
としてJohnMcGの回答が
うまコピーのことをバイナリー毎にTypename、サイズ組み合わせです。
だからこそ思う インライン テンプレート機能です。
回答の詳細はこちら配列のサイズ決定第1部 ここでは:配列のサイズ決定第2部.
のためのC99-スタイルと可変長の配列で、純粋なマクロ的sizeof(arr)/sizeof(arr[0]))のみである。