如何正确创建T类型的模板对象,即T result = T();

时间:2017-09-30 11:05:37

标签: c++14

您好我正在尝试创建一个T类型的对象,其中T是一个指针,通过使用T result = T()。但是它不是调用构造函数,而只是返回一个空指针。

以下是一些受影响代码的示例:

template <class T>
    T readBlockchain(std::ifstream* stream) {
        T result = T(); // Result is null after this
        decltype(result->getLastBlock()) blkPtr = result->getLastBlock();
        auto blk = *blkPtr;
        decltype(result->getLastBlock()) lastBlock = &readBlock<decltype(blk)>(stream);
        if(!lastBlock->verify())
            return nullptr;
        unsigned long count = *readUnsignedLong(stream);
        unsigned long orphanCount = *readUnsignedLong(stream);
        std::map<std::string, decltype(blk)> blocks = std::map<std::string, decltype(blk)>();
        for(int i = 0; i < count - 1; i++){
            decltype(blk) block = readBlock<decltype(blk)>(stream);
            if(!block.verify())
                return nullptr;
            blocks.insert(std::make_pair(block.getHash(), block));
        }
        std::vector<Blockchain<decltype(blk)>*> orphanedChains = std::vector<Blockchain<decltype(blk)>*>();
        for(int i = 0; i < orphanCount - 1; i++){
            Blockchain<decltype(blk)>* orphan = &readOrphanedChain<Blockchain<decltype(blk)>>(stream);
            orphanedChains.push_back(orphan);
        }
        result->setLastBlock(lastBlock);
        result->setCount(count);
        result->setOrphanCount(orphanCount);
        result->setBlocks(blocks);
        result->setOrphanedChains(orphanedChains);
        return result;
    }

1 个答案:

答案 0 :(得分:1)

如果我的理解是正确的。为了正确地概括readBlockchain,当T是指针在堆中创建T的新对象并且T是具体类型时,您会希望通过调用T的构造函数来创建常规T对象。一种解决方案是使用以下特化构造。

template<typename T>
struct CreateNew {
  template<typename... Args>
  static T apply(Args&&... args) { return T(std::forward<Args>(args)...); }
};

template<typename T>
struct CreateNew<T*> {
  template<typename... Args>
  static decltype(auto) apply(Args&&... args) { return std::make_unique<T>(std::forward<Args>(args)...); }
};

也就是说,您可以创建一个模板类,该模板类接受模板参数T以及类型T*指针的该模板类的特化。在主模板(例如,静态成员函数apply)中,您将通过调用类T的构造函数并在专门化内部创建T类型的对象。创建T*的堆对象(请注意,在专门化中,为方便起见,我返回std::unique_ptr<T*>

因此,您的readBlockChain模板函数将变为:

template <class T>
decltype(auto) readBlockchain(std::ifstream* stream) {
  auto result = CreateNew<T>::apply(/* T constructor arguments */);
  ...
  return result;
}

Live Demo

相关问题