-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;
};

当构造这些数据结构的实例时,会在其各自的无序映射(每种数据类型一个)中插入指向该映射的指针,以便可以在需要时访问它们,例如

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

您正在尝试将 a 转换shared_ptr<loadedShipData_t>为 ashared_ptr<loadedStarfieldData_t>的外观。作为猜测,它们可能是不兼容的指针类型,这不起作用的原因与试图loadedShipData_t*从声明为返回 a 的函数返回 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 回答
2

函数模板不是可以在运行时神奇地改变其类型的函数。它根本不是一个函数。这是制作常规、非魔法功能的秘诀。如果你不能用一组固定的类型编写一个函数来做你想做的事情,你也不能编写一个神奇的模板来做这件事。

您正在尝试编写一个返回类型 A 或类型 B 的函数,具体取决于运行时参数。此类函数在 C++ 中不存在,您无法使用模板制作它们。

于 2013-07-28T05:19:51.800 回答