开发者

Unresolved external error

开发者 https://www.devze.com 2023-01-26 20:58 出处:网络
I\'ve written this beauty: #include <iostream> struct something { static const char ref[]; }; const char something::ref[] = \"\";

I've written this beauty:

#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>();
}

It somewhat cleanly converts between string literal types. But when I compile it, MSVC says that the make_liter开发者_如何学JAVAal function is an undefined external function- which is clearly untrue as it's defined right there.

Edit: I've managed to reduce the problem down without all of the template gunk.

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)

It's just a static array. Does life hate me?


The issue is that is that to_literal::hidden is declared but never defined. Take another look:

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 fix this, add a proper definition of 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


When you define static members, a declaration does not suffice. You must provide a definition outside the class. I.e. add

wchar_t some::hidden[40];

outside the class, and it'll be defined.

Otherwise, if C++ allowed this, it'd cause the same problem as defining a global variable in a header -- every .cpp file that includes it will come with a duplicate definition, and at link time you'd get a multiply-defined symbol error.


You're declaring but not defining the static member. Add something like...

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

I tried to check in MSVC for you too, but with VS2005 I get another stupid error...

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

...compiler complains of...

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

Looks like when they fix one bug, there's another one behind it ;-/.


When I built this with VC 2008, that wasn't the error I got. The error was:

Error 1 error LNK2001: unresolved external symbol "private: static wchar_t * to_literal<1,&public: static char const * const something::ref,wchar_t>::hidden" (?hidden@?$to_literal@$00$1?ref@something@@2QBDB_W@@0PA_WA) main.obj Enabler

Removing static from the to hidden[N]; member resolved the issue.

Are you sure you got the error message correct?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号