首页 > 解决方案 > 模板方法特化+通用实现+优化=无限递归?

问题描述

我有以下生成文件来构建以下几个文件。

FLAGS = -O3

release: main Collection
    g++ -o main Collection.o main.o $(FLAGS)

main: main.cpp
    g++ -c main.cpp -std=c++17 $(FLAGS)

Collection: Collection.cpp Collection.hpp
    g++ -c Collection.cpp -std=c++17 $(FLAGS)

clean: main
    rm -f main *.o
/// Collection.hpp

#include <unordered_map>

struct RecallAsIs {
  static constexpr int val = 0;
};

template <int value>
struct RecallAdd {
  static constexpr int val = value;
};

class Collection {
 public:
  Collection();

  ~Collection();

  void Add(int key, int value);

  template <class RecallPolicy = RecallAsIs>
  int Get(int key) const;

 private:
  std::unordered_map<int, int> values_;
};

template <class RecallPolicy>
int Collection::Get(int key) const {
  return Get(key) + RecallPolicy::val;
}
/// Collection.cpp

#include "Collection.hpp"

Collection::Collection() = default;

Collection::~Collection() = default;

void Collection::Add(int key, int value) { values_[key] = value; }

template <>
int Collection::Get<RecallAsIs>(int key) const {
  return values_.at(key);
}
/// main.cpp

#include <iostream>

#include "Collection.hpp"

int main() {
  Collection c;
  c.Add(10, 12);
  std::cout << c.Get(10) << std::endl;
  return 0;
}

关闭优化时,即。setting FLAGS = -O0, 12 被打印到终端。但是,在设置时FLAGS = -O3,程序最终挂起,我不太明白它为什么挂起。我最新的运行理论是,在Collection::Gethpp 的一般实现中,编译器在启用优化并且看不到特化时内联,因此递归调用自身,导致程序挂起。我的分析正确吗?

标签: c++

解决方案


该程序格式错误,无需诊断。

[temp.expl.spec]/6如果模板、成员模板或类模板的成员被显式特化,则应在第一次使用该特化之前声明该特化,这将导致发生隐式实例化,在发生这种使用的每个翻译单元;不需要诊断...


推荐阅读