Неразрешенная внешняя ошибка - PullRequest
1 голос
/ 24 ноября 2010

Я написал эту красоту:

#include <iostream>

struct something {
    static const char ref[];
};

const char something::ref[] = "";

template<int N, const char(&t_ref)[N], typename to> struct to_literal {
private:
    static to hidden[N];
public:
    to_literal() 
    : ref(hidden) {
        for(int i = 0; i < N; i++)
            hidden[i] = t_ref[i];
    }
    const to(&ref)[N];
};

template<int N, const char(&ref)[N], typename to> const to* make_literal() {
    return to_literal<N, ref, to>().ref;
}

int main() {
    const wchar_t* lit = make_literal<sizeof(something::ref), something::ref, wchar_t>();
}

Это несколько чисто конвертирует между строковыми литеральными типами. Но когда я компилирую его, MSVC говорит, что функция make_literal является неопределенной внешней функцией, что явно не соответствует действительности, так как она определена прямо здесь.

Редактировать: мне удалось уменьшить проблему без всех шаблонов.

struct some {
    friend int main();
private:
    static wchar_t hidden[40];
public:
    some() 
    {    
    }
};

int main() {
    std::cout << some::hidden;
    //const wchar_t* lit = make_literal<sizeof(something::ref), something::ref, wchar_t>();
}
main.obj : error LNK2001: unresolved external symbol "private: static wchar_t * some::hidden" (?hidden@some@@0PA_WA)

Это просто статический массив. Жизнь ненавидит меня?

Ответы [ 4 ]

2 голосов
/ 24 ноября 2010

Проблема в том, что to_literal::hidden объявлен, но никогда не определен. Посмотрите еще раз:

struct something {
    static const char ref[];  // declaration of something::ref
};

const char something::ref[] = "";  // definition of something::ref

template<int N, const char(&t_ref)[N], typename to> struct to_literal {
private:
    static to hidden[N];  // declaration of to_literal::hidden (but there's no
                          // definition anywhere)
public:
    to_literal() 
    : ref(hidden) {
        for(int i = 0; i < N; i++)
            hidden[i] = t_ref[i];
    }
    const to(&ref)[N];
};

Чтобы исправить это, добавьте правильное определение to_literal::hidden:

template<int N, const char(&t_ref)[N], typename to>
to to_literal<N, t_ref, to>::hidden[N];  // definition of to_literal::hidden
2 голосов
/ 24 ноября 2010

Вы объявляете, но не определяете статический член.Добавьте что-то вроде ...

template<int N, const char(&t_ref)[N], typename to>
to to_literal<N, t_ref, to>::hidden[N];

Я тоже пытался проверить в MSVC, но с VS2005 получаю еще одну глупую ошибку ...

template<int N, const char(&t_ref)[N], typename to> 
to to_literal<N, t_ref, to>::hidden[N]; 

... компилятор жалуетсяиз ...

error C3860: template argument list following class template name must list parameters in the order used in template parameter list

Похоже, когда они исправляют одну ошибку, за ней стоит другая; - /.

2 голосов
/ 24 ноября 2010

Когда вы определяете статические члены, объявления недостаточно. Вы должны предоставить определение вне класса .Т.е. добавьте

wchar_t some::hidden[40];

вне класса, и он будет определен.

В противном случае, если C ++ допустит это, это вызовет ту же проблему, что и определение глобальной переменной в заголовке- каждый файл .cpp, который включает его, будет иметь дублирующееся определение, и во время компоновки вы получите многократно определенную ошибку символа.

1 голос
/ 24 ноября 2010

Когда я создавал это с VC 2008, это не было ошибкой, которую я получил. Ошибка была:

Ошибка 1, ошибка LNK2001: не устранена внешний символ "частный: статический wchar_t * to_literal <1, & public: static char const * const что-то :: исх, wchar_t> :: скрытый» (? hidden @? $ to_literal @ $ 00 $ 1? ref @ нечто @@ 2QBDB_W @@ 0PA_WA) main.obj Enabler

Удаление static из члена to hidden[N]; решило проблему.

Вы уверены, что правильно получили сообщение об ошибке?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...