代码之家  ›  专栏  ›  技术社区  ›  lordlol

Clang和gcc因模板函数过载而陷入困境

  •  2
  • lordlol  · 技术社区  · 1 年前

    我得上课 Derived1 Derived2 从抽象基类派生 Base .
    我也有一节课 Container ,其中包含指向对象的唯一指针的映射 基地 类,因为我想做运行时多态。
    这个 集装箱 类有一个函数 add 它获取一个指向基类对象的唯一指针,并将其添加到 map 我注意到我经常知道添加对象的具体类型,所以我添加了一个重载的模板化添加函数,该函数按值接收任意对象,将其移动到一个唯一的指针中,并调用另一个 添加 功能。

    下面是一个最小的例子:

    #include <map>
    #include <memory>
    #include <string>
    
    class Base {
        public:
            virtual ~Base();
    };
    
    class Derived1 : Base {
    };
    
    class Derived2 : Base {
    };
    
    class Container {
        public:
            std::map<std::string, std::unique_ptr<Base>> coll;
    
            void add(std::string name, std::unique_ptr<Base> elem) {
                coll.emplace(name, std::move(elem));
            }
    
            template<typename T>
            void add(std::string name, T elem) {
                this->add(name, std::make_unique<T>(std::move(elem)));
            }
    };
    
    int main() {
        Container c;
    
        //a little more convenient than c.add("1", std::make_unique<Derived1>());
        c.add("1", Derived1()); 
    }
    

    当试图用clang-16编译它时,它似乎卡住了,慢慢地使用了越来越多的RAM,直到我的32GB满了。gcc似乎也卡住了,但没有使用越来越多的RAM。

    我可以通过重命名其中一个来修复它 添加 功能,但我仍然很好奇这里发生了什么。

    这是预期的行为,因为我打破了一些不祥的C++规则,你只需要知道吗?我认为编译器卡住是不应该真正发生的事情,不管输入是什么。

    所以,要么我做了一些在其他代码库中没有发生的事情,所以这个编译器错误从未被注意到,要么我做出了一些非常不寻常的事情,以至于除了编译器卡住之外,我从来没有费心去制定一个更清洁的解决方案。这将是我的第二个问题:他们对我的方法有什么看法,以至于这对其他人来说似乎不是问题吗?

    1 回复  |  直到 1 年前
        1
  •  2
  •   wohlstad    1 年前

    此方法模板:

    template<typename T>
    void add(std::string name, T elem) {
         this->add(name, std::make_unique<T>(std::move(elem)));
    }
    

    导致方法实例化的无限循环。

    它最初被称为 T = Derived1 ,
    然后与 T = std::uqniue_ptr<Derived1> ,
    然后与 T = std::uqniue_ptr<std::unique_ptr<Derived1>> ,
    等等。

    编译器不断地实例化这些不同的方法,直到最终内存不足或只是陷入无限循环,试图继续实例化。

    这个问题也发生在MSVC中(在MSVC我最终得到: fatal error C1060: compiler is out of heap space ).

    如果你重命名非模板方法的名称,并从模板化方法调用它(正如你所观察到的),你就打破了这个循环,因此不会出现问题。

    推荐文章