#include <vector>
#include <string>
class __declspec(dllexport) SomeClass
{
private:
std::vector<std::string> avar; // Line 7
public:
std::vector<std::string> * ReturnVar() { return(avar); }
};
When I compile I get C4251 warning:
"myheader.h(7) : warning C4251: 'avar' : class 'std::vector<class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >,class std::allocator<class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > > >' needs to have dll-interface to be used by
clients of class 'SomeClass'"
Huh ! My class is a C++ standard class template instantiation. When it used
it will be instantiated by the user.
Anyway, to satisfy the compiler, in order to export the class I write, in
the same DLL:
template class __declspec(dllexport) std::vector<std::string>;
Is this what is needed ? If so, why ?
"Edward Diener" <eddi...@tropicsoft.com> wrote in message
news:OD7vo1cOCHA.1976@tkmsftngp11...
"Eugene Korobko" <ekor...@yandex.ru> wrote in message
news:efXwMifOCHA.2592@tkmsftngp09...
You are correct. In this case, the warning is spurious and may be
ignored or disabled.
> Anyway, to satisfy the compiler, in order to export the class I write, in
> the same DLL:
>
> template class __declspec(dllexport) std::vector<std::string>;
>
> Is this what is needed ? If so, why ?
No, this is not needed, though I don't imagine it would hurt anything
and might even avoid causing each client to generate this instantiation.
I'm not sure the syntax is right, though... I think to export a
template instantiation, you need to use the "extern" keyword.
Exactly. It will be instantiated when compiling every client.
Furthermore inline functions (all functions :) will be expanded
at every call.
> Anyway, to satisfy the compiler, in order to export the class I write, in
> the same DLL:
>
> template class __declspec(dllexport) std::vector<std::string>;
>
> Is this what is needed ? If so, why ?
If you want the only dllexported copy of the functions be
used in every client, you need this before YourHeader.H
in the module you want it be instantiated and dllexported.
You need
template class __declspec(dllimport) std::vector<std::string>;
before YourHeader.H in all other modules to suppress
instantiation. And you need to compile them with Ob0
option to suppress inlining.
Actually no one goes that far and I suspect everyone
has this warning disabled :)
Sergei
I say this because in place of std::string I change to a nested class of an
exported class instead, and all efforts to provide an exported template
instantiation of a vector of this nested class leads to failure, so i just
assume the compiler is broke and can't do it:
----------------------------------------------------------------------------
---------------------------------------------------
#include <string>
#include <vector>
#if defined(BUILDING_SOMECLASS)
#define SOMECLASS_IMPORT_EXPORT __declspec(dllexport)
#else
#define SOMECLASS_IMPORT_EXPORT __declspec(dllimport)
#endif
class SOMECLASS_IMPORT_EXPORT SomeClass
{
public:
class MyNestedClass { public: std::string x; int y; bool operator < (const
MyNestedClass & oth) { return(x < oth.x ); } };
private:
std::vector<MyNestedClass> avar;
public:
std::vector<MyNestedClass> * ReturnVar() { return(avar); }
};
template class SOMECLASS_IMPORT_EXPORT
std::vector<SomeClass::MyNestedClass>;
----------------------------------------------------------------------------
---------------------------------------------------
Then with BUILDING_SOMECLASS defined:
C:\PROGRAM Files\Microsoft Visual Studio\VC98\INCLUDE\xutility(50) : error
C2678: binary '<' : no operator defined which takes a left-hand operand of
type 'const struct SomeClass::MyNestedClass' (or there is no acceptable
conversion)
C:\PROGRAM Files\Microsoft Visual Studio\VC98\INCLUDE\vector(218) : see
reference to function template instantiation 'bool __cdecl
std::lexicographical_compare(const struct SomeClass::MyNestedClass *,const
struct SomeClass::MyNestedClass *,const struct SomeClass::MyNestedClass
*,const struct SomeClass::MyNestedClass *)' being compiled
The compiler obviously isn't parsing the nested type correctly.
"Sergei" <ser...@summertime.mtu-net.ru> wrote in message
news:#gHZAJjOCHA.1724@tkmsftngp13...
See this message:
http://groups.google.com/groups?selm=2h9vrto0kglebcsdg012c1r13jfck1dfdm%404ax.com
--
Doug Harrison
Microsoft MVP - Visual C++
Eluent Software, LLC
http://www.eluent.com
Tools for VC++, VS.NET, and Windows
This is a whole nother thing. You need a non-member version of the operator:
class MyNestedClass {
friend bool operator < (const MyNestedClass &l, const MyNestedClass &r) {
return l.x < r.x ;
}
public:
std::string x;
int y;
};
Sergei
Well, declaring the member-operator const would suffice:
class MyNestedClass {
public:
std::string x;
int y;
bool operator < (const MyNestedClass & oth) const { return x < oth.x; }
};
Though anyway the non-member version is better.
Sergei