2017-08-27 20 views
0

関数で渡されたパラメータはconstプロパティを維持できないようです。 関数内のパラメータの情報を使用してconst変数を初期化し、次に配列型を作成する必要があるとします。どのようにできるのか?関数でconst変数を渡すには?

例:

#include <array> 
using namespace std; 

void foo(const int info) 
{ 
    const int num = info + 1; // seems num cannot be constant 
    array<int, num> arr; 
} 

コンパイルエラー:

test.cpp: In function ‘void foo(int)’: 
test.cpp:8:16: error: the value of ‘num’ is not usable in a constant expression 
array<int, num> arr; 
      ^
test.cpp:7:15: note: ‘num’ was not initialized with a constant expression 
    const int num = info + 1; // seems num cannot be constant 
      ^

アップデート:そのようなトラブルの原因となる配列型を使用して、単純な型の配列を使用して だけでOKです:

void foo(int info) 
{ 
    int array[info]; 
} 

コンパイル時にinfoを割り当てる必要はありませんか?

+1

あなたが取得している実際のコンパイルエラーとは何ですか?テンプレートパラメータの引数としてランタイム変数を使用することはできません( 'const'は' constexpr'と同じではありません)。 – Dai

+1

Numはコンパイル時定数でなければなりません。配列のサイズとして使用したいのですか? 'const'は再割り当てできないことを意味し、コンパイル時には定数ではありませんafaik – Carcigenicate

+1

std :: arrayはコンパイル時定数が必要です。関数パラメータはコンパイル時定数にすることはできません。代わりにstd :: vectorが必要です。 –

答えて

1

はC++でconstconstexprの違いがあります:あなたのケースではDifference between `constexpr` and `const`

、あなたはconstexprのを必要とし、コンパイル時のサイズの配列を作成しようとしています。 constexprは単純にconst変数の関数の引数ではありません。代わりにconstexprを使用するか、arrayの代わりにvector(実行時サイズの配列)を使用できます。

+0

ありがとう、私はconstexprについて読むが、それでもconstexprとして使用される関数パラメータを作る方法を理解できない。あなたは私に例を挙げることができますか? – JiangFeng

+0

@ JiangFeng:関数のパラメータをconstexprにしたい場合は、ここでJeff Garrettの答えが示すように、テンプレートパラメータにすることができます。あなたはそれをあなたがしたように通常の議論にすることはできません。ほとんどの場合、この種のコードには 'array'の代わりに' vector'を使うべきです。 –

0

動的サイズの配列が必要で、std :: arrayの特定のプロパティを必要としない場合は、単にvectorを使用できます。

主な違いは次のとおりです。

std::array is a template class that encapsulate a statically-sized array, stored inside the object itself, which means that, if you instantiate the class on the stack, the array itself will be on the stack. Its size has to be known at compile time (it's passed as a template parameter), and it cannot grow or shrink.

ベクトル内部には、しかし、ヒープ上に格納されています。

から:https://stackoverflow.com/a/4424658/128581

さらにはstd ::型Tが自明コピー可能である場合、配列は(あなたが心配することなく、ある場所から別の場所にそれをmemcpyをすることができます意味)自明コピー可能です。あなたはgcc -pedanticでコンパイルする場合、あなたはそのint array[info]も、標準C++ではないでしょう

void foo(size_t size) 
{ 
    vector<int> arr(size); 
} 
1

使用は次のようにベクトル。 the GCC docsを参照してください。質問の目標を達成するために

一つの方法は、非型テンプレートパラメータである:

#include <array> 

template<int info> 
void foo() 
{ 
    constexpr int num = info + 1; 
    std::array<int, num> arr; // or int arr[num] 
} 
// Call as foo<3>() 
関連する問題