-1

テンプレート化されたデータ管理関数で共有ポインタを動作させるのに問題があります。さまざまなオブジェクトのロードされたデータを含む単純な構造体がいくつかあります。

struct loadedShipData_t {
    enum VARIABLES {
        // snip for readability: lots of variable names for identification
    };

    std::string textureKey;
    std::array<int, 20> data;
};

struct loadedStarfieldData_t {
    enum VARIABLES {
        // snip for readability: lots of variable names for identification
    };

    std::array<int, 8> data;
};

これらのデータ構造体のインスタンスが構築されると、そこへのポインターがそれぞれの順不同マップ (データ型ごとに 1 つ) に挿入されるため、必要なときにいつでもアクセスできます。

std::unordered_map<std::string, std::shared_ptr<loadedShipData_t>> shipData;
std::unordered_map<std::string, std::shared_ptr<loadedStarfieldData_t>> starfieldData;

...などなど。

実装に問題があるテンプレート化された関数は getData と呼ばれるもので、キーを指定すると、順序付けされていないマップに格納されたデータ構造体へのポインターを返します。

template <typename DATA>
    std::shared_ptr<DATA> getData(DATA_TYPES dataType, const std::string& key) {
        switch (dataType) {
            case STARFIELD_DATA:
                return starfieldData.at(key);
            case SHIP_DATA:
                return shipData.at(key);
            // snip for readability: all the other data types
            default:
                throw UNDEFINED_DATA_TYPE();
                break;
        };
    }

この関数は次のように呼び出されます。

std::shared_ptr<loadedStarfieldData_t> loadedData = data.getData<loadedStarfieldData_t>(STARFIELD_DATA, key);
std::shared_ptr<loadedShipData_t> loadedShipData = data.getData<loadedShipData_t>(SHIP_DATA, "Debug");

そしてエラーメッセージ:

<file_path> error C2664: 'std::shared_ptr<_Ty>::shared_ptr(std::nullptr_t)' : cannot convert parameter 1 from 'std::shared_ptr<_Ty>' to 'std::nullptr_t'
          with
          [
              _Ty=loadedShipData_t
          ]
          and
          [
              _Ty=loadedStarfieldData_t
          ]
          nullptr can only be converted to pointer or handle types
          <file_path> : see reference to function template instantiation 'std::shared_ptr<_Ty> DataManager::getData<loadedShipData_t>(DATA_TYPES,const std::string &)' being compiled
          with
          [
              _Ty=loadedShipData_t
          ]
<file_path> error C2664: 'std::shared_ptr<_Ty>::shared_ptr(std::nullptr_t)' : cannot convert parameter 1 from 'std::shared_ptr<_Ty>' to 'std::nullptr_t'
          with
          [
              _Ty=loadedStarfieldData_t
          ]
          and
          [
              _Ty=loadedShipData_t
          ]
          // snip for readability: other data types
          nullptr can only be converted to pointer or handle types
          <file_path> : see reference to function template instantiation 'std::shared_ptr<_Ty> DataManager::getData<loadedStarfieldData_t>(DATA_TYPES,const std::string &)' being compiled
          with
          [
              _Ty=loadedStarfieldData_t
          ]
          // snip for readability: other data types

私は何度も何度もコードを調べてめちゃくちゃにしてきたので、他の誰かが同様の問題に遭遇したかどうかを確認したいと思いました. ここで同様の質問をいくつか見つけましたが、何が問題なのかを理解できませんでした。そのため、自分の問題の詳細を投稿し、これらの部分の C++ の専門家が私を指摘できるかどうかを確認することにしました。正しい方向。

お時間をいただきありがとうございます。

PS 私は Visual Studio 2012 でコンパイルしています。

4

2 に答える 2

4

見た目shared_ptr<loadedShipData_t>から a を aに変換しようとしています。shared_ptr<loadedStarfieldData_t>おそらく、これらは互換性のないポインター型であり、 aloadedShipData_t*を返すように宣言された関数から aを返そうとしても機能しないのと同じ理由で、これは機能しloadedStarfieldData_t*ません。

これを拡張するには、次の行:

std::shared_ptr<loadedStarfieldData_t> loadedData = data.getData<loadedStarfieldData_t> STARFIELD_DATA, key);

テンプレートは基本的に次のようになります。

std::shared_ptr<loadedStarfieldData_t> getData(DATA_TYPES dataType, const std::string& key) {
    switch (dataType) {
        case STARFIELD_DATA:
            return starfieldData.at(key);
        case SHIP_DATA:
            return shipData.at(key); // <-- type mismatch here
        // snip for readability: all the other data types
        default:
            throw UNDEFINED_DATA_TYPE();
            break;
    };
}
于 2013-07-28T05:09:19.183 に答える