2017-12-20 4 views
1

は、以下のコードを検討:目的は持っているだろうは静的定数STDに可変長テンプレートリストから整数値を割り当て::アレイメンバ

MyClass<1,5,7,9> myClass; 

:としてクラスを使用その後

template<unsigned... IDs> 
class MyClass{ 
public: 
    static const std::array<unsigned, sizeof...(IDs)> ids { IDs... }; 
    PinIDs() = default; 
}; 

をサイズが4のidsで、値はそれぞれ(1,5,7,9)です。

このタイプのオブジェクトは使用できますか、静的修飾子を削除する必要がありますか?そうでない場合、静的修飾子でどのように記述しますか?オブジェクトはデフォルトで構成可能である必要があります。


EDIT:

私はアップル初のソリューションを試してみましたが、win7の 上のMSのVisual Studio 2017 CEと私は、このコンパイラエラーました:このような完全なオリジナルのソースで

1>------ Build started: Project: PracticeMath, Configuration: Debug Win32 ------ 
1>stdafx.cpp 
1>PracticeMath.cpp 
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(33): error C2988: unrecognizable template declaration/definition 
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(33): error C2143: syntax error: missing ';' before '<' 
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(33): error C2059: syntax error: '<' 
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(33): error C2039: 'ids': is not a member of '`global namespace'' 
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(33): error C2143: syntax error: missing ';' before '{' 
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(33): error C2447: '{': missing function header (old-style formal list?) 
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(38): error C2065: 'myId': undeclared identifier 
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(39): error C2065: 'myId': undeclared identifier 
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(40): error C2065: 'myId': undeclared identifier 
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(44): error C2065: 'c': undeclared identifier 
1>Done building project "PracticeMath.vcxproj" -- FAILED. 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

を:

#include <iostream> 
#include <array> 

template<unsigned... IDs> 
class PinIDs{ 
public: 
    static const std::array<unsigned, sizeof...(IDs)> ids; 

    PinIDs() = default; 

    const unsigned& operator[](unsigned idx) const { 
     return ids[idx]; 
    } 
}; 

template<unsigned... IDs> 
const std::array<unsigned, sizeof...(IDs)> PinIDs<IDs...>::ids { IDs... }; 

int main() { 
    PinIDs<4, 17, 19> myId; 

    std::cout << myId[0] << " "; 
    std::cout << myId[1] << " "; 
    std::cout << myId[2] << " "; 

    std::cout << "\nPress any key and enter to quit." << std::endl; 
    char c; 
    std::cin >> c; 

    return 0; 
} 

私はアップルの1st methodを適用しようとしたときに私の溶液中のクラスの実際の名前とは対照的に、私は誤ってMyClassを混同しているという事実育てるストーリーテラーのおかげ - プロジェクトを。一度私はそれがコンパイルして、ビルドし、期待通りに実行することを訂正しました。

+1

試しましたか? – StoryTeller

+0

はい。しかし、問題を抱えていました... 'template'構文ビジネスか、単に' static'を使用しているのか分かりません... –

+0

"問題がある"場合は、エラーを貼り付けてください –

答えて

3

あなたはリンゴの答えを@appleを参照してください。この


#include <array> 

template<unsigned... IDs> 
class MyClass{ 
public: 
    static const std::array<unsigned, sizeof...(IDs)> ids; 
    MyClass() = default; 
}; 

template<unsigned... IDs> 
const std::array<unsigned, sizeof...(IDs)> MyClass<IDs...>::ids {IDs...}; 

int main(){ 
    MyClass<1,5,7,9> myClass; 
    return myClass.ids[0]; 
} 

やconstexprの/インラインを使用します(++ 17 Cの両方が必要)


#include <array> 
template<unsigned... IDs> 
class MyClass{ 
public: 
    //static constexpr std::array<unsigned, sizeof...(IDs)> ids{IDs...};//or this 
    static inline const std::array<unsigned, sizeof...(IDs)> ids{IDs...}; 
    MyClass() = default; 
}; 

int main(){ 
MyClass<1,5,7,9> myClass; 
    return myClass.ids[0]; 
} 
+0

まあまあ近く。私は 'static'修飾子なしでクラスが期待どおりに動くようにすることができました。ちょうど私が静的型のメンバー変数を作成しようとしたとき。私はちょっとしたトラブルに遭っていました。 –

+0

@FrancisCugler - これは、静的メンバーで行う方法です。クラス外で定義する必要があります。 – StoryTeller

+0

また、 'array'に直接インデックスするクラスに' operator [] 'を追加したいので、' object.ids [] 'や' MyClass :: ids [] 'を使用する必要はありません –

1

を試すことができます基本については私はちょうどそれを行うためにC + + 17の方法を追加します。あなたの元の試みにかなり近いです。ただ、変数にinline指定子を追加します。

template<unsigned... IDs> 
class MyClass{ 
public: 
    static inline const std::array<unsigned, sizeof...(IDs)> ids{ { IDs... } }; 
    MyClass() = default; 
}; 

今の宣言は、定義を兼ねることができます。ああ、中括弧に気をつけてください。 std::arrayを集約として初期化する必要があります。したがって、std::arrayの場合は{}の1つのペアと、それが保持する内部のローの配列の場合は1つです。

+0

hmm私はあなたが 'member functions'で' inline'を使うことができると知っていました。あなたは 'メンバ変数'でそれを使うことができるのかどうか分かりませんでした。... –

+0

@FrancisCugler - C++から17以降です。 – StoryTeller

+0

ああ大丈夫だよね。 MS Visual Studioがおそらく不足している新しい言語機能。 –

0

online compiler, supporting c++17で試してみませんか?

template<unsigned... IDs> 
class MyClass{ 
public: 
    static constexpr std::array<unsigned, sizeof...(IDs)> ids { IDs... }; 
    MyClass() = default; 
}; 

が問題ありません。コンパイル時に計算される変数にstatic const inlineは必要ありません。static constexpr

+0

は 'constexpr'デフォルトコンストラクタブルですか? –

+1

@FrancisCugler、 'constexpr'値はコンパイル時に計算されます。 'static'フィールドは、(デフォルトのコンストラクタービリティを含めて)クラスの型特性に干渉することはありません。 –

+1

* "constexpr値が計算される" * - いいえ、コンパイル時に計算される可能性があります。そして、それでもアレイはストレージを占有する可能性が高いです。 'operator []'はODRを使用するためです。 – StoryTeller

関連する問題