Явное создание экземпляра статической функции-члена шаблона продолжает не компилироваться с сообщением error C2785: 'at_Intermediate CUtil::convert_variant(const VARIANT &)' and '<Unknown>' have different return types.
Когда я создаю соответствующий класс с нестатическими функциями-членами, я нравлюсь компилятору.
// utility class - static methods
struct CUtil {
template< typename at_Intermediate > static at_Intermediate convert_variant( const VARIANT &v ) ;
template<> static VARIANT convert_variant<VARIANT >( const VARIANT &v ) { return v; } //
template<> static double convert_variant<double >( const VARIANT &v ) { return v.dblVal; }
template<> static long convert_variant<long >( const VARIANT &v ) { return v.lVal ; }
template<> static BSTR convert_variant<BSTR >( const VARIANT &v ) { return v.bstrVal; }
};
Это составленный вопрос:
Почему компилятор жалуется на функцию «Неизвестно», когда она явно известна?
Что вызывает это сообщение - оно исчезает, когда функция становится глобальной или нестатической.
Обновлено:
после некоторых полезных советов от Джоша: нельзя ли явно создавать экземпляры шаблонных функций в объявлении класса?





Попробуйте так:
struct CUtil {
template< typename T >
static T convert_variant(const VARIANT &);
};
template<> int CUtil::convert_variant<int>(const VARIANT &);
template<> VARIANT CUtil::convert_variant<VARIANT>(const VARIANT &);
Вы не можете явно специализировать шаблон внутри области класса. Глянь сюда.
Странная проблема VS2008 в том, что это действительно работает.
struct CUtil {
template< typename T >
static T convert_variant(const VARIANT &);
template<>
static int convert_variant<int>(const VARIANT &);
};
И это:
struct CUtil {
template< typename T > static void convert_variant(T);
template<> static void convert_variant<VARIANT >(VARIANT);
};
на Codepad.org: тот же результат (явная специализация в области без пространства имен 'struct CUtil')
ваше третье решение должно избавиться от ключевого слова static (вы там не объявляете)
Кстати, хотя вы не получили ответа, я поставил +1 к вашему сообщению, потому что это действительно помогло мне найти проблему.
По-видимому, вы можете использовать только явную специализацию шаблона в области пространства имен, хотя я не могу найти этого в стандарте (но GCC говорит об этом). Для меня работает следующее (на GCC):
struct CUtil {
template< typename at_Intermediate > static at_Intermediate convert_variant( const VARIANT &v ) ;
};
template<> VARIANT CUtil::convert_variant<VARIANT >( const VARIANT &v ) { return v; }
template<> double CUtil::convert_variant<double >( const VARIANT &v ) { return v.dblVal; }
template<> long CUtil::convert_variant<long >( const VARIANT &v ) { return v.lVal ; }
template<> BSTR CUtil::convert_variant<BSTR >( const VARIANT &v ) { return v.bstrVal; }
РЕДАКТИРОВАТЬ Это является в стандарте:
14.7.2.5:
An explicit instantiation of a class or function template specialization is placed in the namespace in which the template is defined. An explicit instantiation for a member of a class template is placed in the namespace where the enclosing class is defined. An explicit instantiation for a member template is placed in the namespace where the enclosing class or class template is defined.
(Все выделено мной.)
это явная специализация, а не создание экземпляра. 14.7.3p2: «Явная специализация должна быть объявлена в пространстве имен, членом которого является шаблон, или, для шаблонов членов, в пространстве имен, членом которого является включающий класс или включающий шаблон класса». подходит в вашем случае :)
ах, nvm, я просто вижу, что OP тоже использовал это, не твоя вина :) но, может, ты сможешь его поправить?
это OriginalPoster, парень разместил вопрос. Я думаю, вы знаете, в чем разница между ними, но в случае, если нет: явное создание экземпляра создаст экземпляр шаблона для данного типа в текущей единице перевода (так что клиенты могут использовать шаблон где-то еще без необходимости ...
... код шаблона. явная специализация помещает разный код для разных типов. (в вашем коде разница в том, что вы возвращаете разных участников в каждой специализации).
@litb: В моем понимании явная специализация на самом деле также является является экземпляром. Хотя я могу ошибаться. Особенно учитывая, что для создания экземпляра существует отдельный синтаксис.
@litb: Пожалуйста, обратите внимание на pastie.org/356862. AFAIK, это не должно работать, если специализация шаблона также не создала экземпляр шаблона.
... Comeau также реагирует на явное создание экземпляра в теле класса ... Определение внешних функций дает нормальный результат.