Ошибка компиляции C ++ 11, неопределенная ссылка, явное создание экземпляра класса шаблона внутри другого класса - PullRequest
0 голосов
/ 18 сентября 2018

Я попытался выполнить поиск в 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, класс field_t не имеет внешней связи (при создании экземпляра статического класса constexpr field_t), что позволяет обойти класс других полей.

1 Ответ

0 голосов
/ 21 сентября 2018

Похоже, я обошёл проблему с компоновщиком, определив поля вне структуры "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;
}
...