代码之家  ›  专栏  ›  技术社区  ›  Andre Marin

C++ 11编译失败、未定义引用、在另一个类中显式模板类实例化

  •  1
  • Andre Marin  · 技术社区  · 6 年前

    我尝试在stackoverflow中搜索这个例子,但是我发现的并不能解决我所看到的问题。

    我看到以下编译错误

    :(.text.startup+0x7):未定义对“fields::second”的引用

    对于此示例代码段:

    #include <iostream>
    #include <string>
    
    enum selector
    {
        SELECTOR_ONE,
        SELECTOR_TWO,
    };
    
    template <selector E>
    struct field_t
    {
        size_t value;
        constexpr field_t(const size_t i):value(i){}
    };
    
    struct fields
    {
        static constexpr field_t<selector::SELECTOR_ONE> FIRST{0};
        static constexpr field_t<selector::SELECTOR_TWO> SECOND{1};
    };
    
    int main()
    {
        std::cout << fields::SECOND.value << std::endl;
        return 0;
    }
    

    我实际上可以通过执行以下修改来进行编译

    #include <iostream>
    #include <string>
    
    enum selector
    {
        SELECTOR_ONE,
        SELECTOR_TWO,
    };
    
    template <selector E>
    struct field_t
    {
        size_t value;
        constexpr field_t(const size_t i):value(i){}
    };
    
    template <selector E>
    struct fields
    {
        static constexpr field_t<E> FIRST{0};
        static constexpr field_t<E> SECOND{1};
    };
    
    int main()
    {
        std::cout << fields<SELECTOR_TWO>::SECOND.value << std::endl;
        return 0;
    }
    

    我只是有点困惑为什么前者不能编译,因为实际上我希望使用默认的模板类实例化。因为我使用C++ 11,FieldIt类没有外部链接(当实例化静态CONTXPREFIELT类)时,这是其他字段类规避的原因。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Andre Marin    6 年前

    看起来我通过定义“fields”结构之外的字段来解决链接器问题。这很奇怪,因为在静态constexpr中使用数值时,我从来没有遇到过这个问题。

    #include <iostream>
    #include <string>
    
    enum selector
    {
        SELECTOR_ONE,
        SELECTOR_TWO,
    };
    
    template <selector E>
    struct field_t
    {
        size_t value;
        constexpr field_t(const size_t i):value(i){}
    };
    
    struct fields
    {
        static constexpr field_t<selector::SELECTOR_ONE> FIRST{0};
        static constexpr field_t<selector::SELECTOR_TWO> SECOND{1};
    };
    
    // This fixes the compile error
    constexpr field_t<selector::SELECTOR_ONE> fields::FIRST;
    constexpr field_t<selector::SELECTOR_TWO> fields::SECOND;
    
    int main()
    {
        std::cout << fields::SECOND.value << std::endl;
        return 0;
    }
    
    推荐文章