часто, бывает так, что некоторый шаблон юзается только в приватной части некоторого класса. но, как известно, специализировать шаблоны в классе — нельзя.
но логика подсказывает, что, т.к. этот шаблон юзается только в приватной части класса — было бы логично его не выносить наружу. но приходится...
Здравствуйте, niXman, Вы писали:
X>часто, бывает так, что некоторый шаблон юзается только в приватной части некоторого класса. но, как известно, специализировать шаблоны в классе — нельзя. X>но логика подсказывает, что, т.к. этот шаблон юзается только в приватной части класса — было бы логично его не выносить наружу. но приходится...
X>как вы поступаете в этом случае?
поступаем как требует язык (т.е. специализируем снаружи). Эстетические хотелки — это, конечно, хорошо, но язык у нас такой, какой есть.
Здравствуйте, niXman, Вы писали:
X>приветствую!
X>часто, бывает так, что некоторый шаблон юзается только в приватной части некоторого класса. но, как известно, специализировать шаблоны в классе — нельзя. X>но логика подсказывает, что, т.к. этот шаблон юзается только в приватной части класса — было бы логично его не выносить наружу. но приходится...
X>как вы поступаете в этом случае?
X>благодарю.
// .hstruct type {
private:
template<bool>
struct wrapper;
};
// .cpp
// пользователю не надо знать, как приватный класс специализируется.template<>
struct type::wrapper<true> {};
template<>
struct type::wrapper<false> {};
Здравствуйте, Кодт, Вы писали:
К>Если проблема изоляции реально существует (нужно разорвать зависимости, ускорить компиляцию, и т.п.), то пимпл.
нет, эстетики ради.
понял. вопрос закрыт.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>приветствую!
X>часто, бывает так, что некоторый шаблон юзается только в приватной части некоторого класса. но, как известно, специализировать шаблоны в классе — нельзя.
А точно нельзя? Ваш код конечно не скомпилируется,
а вот такой скомпилируется:
struct type {
private:
template<typename Fake, bool def>
struct wrapper;
template<typename Fake>
struct wrapper<Fake, true> {
static const int C = 17;
};
template<typename Fake>
struct wrapper<Fake, false> {
static const int C = 18;
};
};
prog.cpp: In member function ‘T type<Types>::get()’:
prog.cpp:7:44: error: expected primary-expression before ‘int’
return checker_helper<void, true>::apply<int>(1);
^
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
X>да, помогло! спасибо огромное!
X>подскажи плиз, в каких случаях нужно использовать template перед вызовом функций? и как вообще эта проблема и ее решение называется?
Ключевое слово template в данном случае не имеет отношение к вызову функции, она квалифицирует следующее за ним имя apply.
Оно указыает компилятору, что это имя некоторого шаблона в класса checker_helper<void, true>. Без такого указания компилятор не может правильно распарзить выражение.
Следующий за apply токен < может быть или началом списка аргументов шаблона, или знаком операции. Не имея квалификации apply не всегда возможно определить, что именно.
Источник этой проблемы -- двойное использование < и > как знаков операций и как шаблонных скобок.
Здравствуйте, niXman, Вы писали:
X>подскажи плиз, в каких случаях нужно использовать template перед вызовом функций? и как вообще эта проблема и ее решение называется?
Смысл примерно такой же как и у typename — нужно сделать "подсказку" компилятору, disambiguate:
14.2/4 When the name of a member template specialization appears after . or -> in a postfix-expression or after a nested-name-specifier in a qualified-id, and the object expression of the postfix-expression is type-dependent or the nested-name-specifier in the qualified-id refers to a dependent type, but the name is not a member of the current instantiation (14.6.2.1), the member template name must be prefixed by the keyword template.
Otherwise the name is assumed to name a non-template. [ Example:
struct X {
template<std::size_t> X* alloc();
template<std::size_t> static X* adjust();
};
template<class T> void f(T* p) {
T* p1 = p->alloc<200>(); // ill-formed: < means less than
T* p2 = p->template alloc<200>(); // OK: < starts template argument list
T::adjust<100>(); // ill-formed: < means less than
T::template adjust<100>(); // OK: < starts template argument list
}