Экспорт класса STL из DLL - почему нет предупреждения от возвращаемого типа?

Мой вопрос связан с экспортом класса C ++ с STL внутри. Например:

class __declspec(dllexport) Hello
{
    std::string   name;

public:
    std::string&  getName();
    void          setName(const std::string& name);
}

Различные статьи, кажется, указывают, что этоочень плохо, что вполне понятно. Все должно быть скомпилировано с теми же настройками компилятора и версией CRT. Иначе все рухнет и сгорит.

Вопрос:

Чего я не понимаю, так это того, почему проблема возникает только у членов данных. С кодом ниже я получаю:C4251: должен иметь dll-интерфейс для использования клиентами класса"; что, по-видимому, исправлено путем экспорта экземпляра std :: string:

struct __declspec(dllexport) SomeClass
{
    // Removes the warning?
    // http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html
    //   template class __declspec(dllexport) std::string;

    std::string name;  // Compiler balks at this
}

И исправленная версия:

// Export the instantiations of allocator and basic_string
template class __declspec(dllexport) std::allocator<char>;
template class __declspec(dllexport) std::basic_string<char, std::char_traits<char>, std::allocator<char> >;

struct __declspec(dllexport) SomeClass
{
    std::string name;  // No more balking!
}

(Это даст LNK2005 «basic_string уже определено», когда вы попытаетесь использовать DLL, что означает, что вы не должны ссылаться в CRT на клиенте - так что в конечном итоге он использует инстанцирование в DLL).

Типы возвращаемых данных и аргументы, по-видимому, не имеют проблем с STL и не получают те же данные обработки, которые получают члены от компилятора.

// No exporting required?
struct __declspec(dllexport) SomeOtherClass
{
    std::string  doSomething1();                       // No problemo
    void         doSomething2(const std::string& s);   // No problemo
}
Дополнительная информация (вопрос выше)

В обоих:

class A {
    std::string foo() { return std::string(); }
    // std::string& foo(); gives the same result!
    // std::string* foo(); also gives the same result!
}

class B {
    std::string a;
}

Похоже, ни один из них не экспортирует std :: basic_string или std :: allocator. Скорее они экспортируют только члены / функции класса.

Однакоисправлено Версия, упомянутая в вопросе, экспортирует как basic_string, так и allocator.

Ответы на вопрос(2)

Ваш ответ на вопрос