шаблон в шаблоне, и реализация вне шаблона
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.11.13 15:41
Оценка:
приветствую!

название какое-то оно сумбурное получилось...

итак.
имеем такой класс:
template<typename T>
struct type {
    struct impl;

    type();
    ~type();

    void m();

private:
    impl *pimpl;
};

для него, чтоб привести реализацию вне класса но в той же единице трансляции, делаем такое:
// пустышка. только компиляции ради.
template<typename T>
struct type<T>::impl {};

// реализация конструктора/деструктора/m()
template<typename T>
type<T>::type()
    :pimpl(new type<T>::impl)
{}

template<typename T>
type<T>::~type()
{ delete pimpl; }

template<typename T>
void type<T>::m()
{std::cout << "ping!" << std::endl;}


тут все понятно.

проблема в том, что класс 'type::impl' должен так же быть шаблоном.
таким образом, мы имеет это:
template<typename T>
struct type {
    template<typename>
    struct impl;

    type();
    ~type();

    void m();

private:
    impl<T> *pimpl;
};


все, на этом мои мысли закончились настолько, что никак не могу понять, каким в этом случае должно быть это выражение?:
template<typename T>
struct type<T>::impl {};



благодарен.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: шаблон в шаблоне, и реализация вне шаблона
От: Conr Россия  
Дата: 14.11.13 15:51
Оценка: 12 (1) +1
Здравствуйте, niXman, Вы писали:

X>все, на этом мои мысли закончились настолько, что никак не могу понять, каким в этом случае должно быть это выражение?:

X>
X>template<typename T>
X>struct type<T>::impl {};

X>


template<typename T>
template<typename A>
struct type<T>::impl {};

?
Re: шаблон в шаблоне, и реализация вне шаблона
От: Evgeny.Panasyuk Россия  
Дата: 14.11.13 15:52
Оценка: 12 (1) +1
http://coliru.stacked-crooked.com/a/2df89ca44cb6ba9a
template<typename T>
struct Foo
{
    template<typename> struct impl;
    T x;
};

template<typename T>
template<typename U>
struct Foo<T>::impl
{
    U x;
    T y;
};

template<typename> void type_is();

int main()
{
    type_is<decltype( Foo<int>{}.x )>();
    type_is<decltype( Foo<int>::impl<double>{}.x )>();
    type_is<decltype( Foo<int>::impl<double>{}.y )>();
}

main.cpp:(.text.startup+0x5): undefined reference to `void type_is<int>()'
main.cpp:(.text.startup+0xa): undefined reference to `void type_is<double>()'
main.cpp:(.text.startup+0xf): undefined reference to `void type_is<int>()'
Re: шаблон в шаблоне, и реализация вне шаблона
От: Abyx Россия  
Дата: 14.11.13 15:58
Оценка:
Здравствуйте, niXman, Вы писали:

если у тебя всегда impl<T>, то зачем вообще тебе делать impl шаблоном?

template<typename T>
struct type {
    struct impl;
    impl* pimpl;
};

template<typename T>
struct type<T>::impl { T t; };
In Zen We Trust
Re[2]: шаблон в шаблоне, и реализация вне шаблона
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.11.13 16:03
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, niXman, Вы писали:


A>если у тебя всегда impl<T>, то зачем вообще тебе делать impl шаблоном?

я это понимаю.
impl берет часть параметров от type, и часть своих.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: шаблон в шаблоне, и реализация вне шаблона
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.11.13 16:08
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

по твоему мотиву, пытаюсь сделать так:
template<typename T>
struct type {
    template<typename>
    struct impl;

    type(); // <<<<<<<<<<<<<<<<<<<<<<<<< 141
    ~type();

    void m();

private:
    impl<T> *pimpl;
};

template<typename T>
template<typename A>
struct type<T>::impl {
    T t;
    A a;
};

template<typename T>
template<typename A>
type<T>::type() // <<<<<<<<<<<<<<<<<<<<<<< 159
    :pimpl(new type<T>::impl<A>)
{}

и получаю такую ошибку:

main.cpp:159:1: error: prototype for 'type<T>::type()' does not match any in class 'type<T>'
type<T>::type()
main.cpp:141:2: error: candidate is: type<T>::type()
type();

ЧЯДНТ?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: шаблон в шаблоне, и реализация вне шаблона
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.11.13 16:10
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

еще вопрос.

вот тут, к примеру, имеет значение порядок записи параметров T и U ?
EP>template<typename T>
EP>template<typename U>
EP>struct Foo<T>::impl
EP>{
EP> U x;
EP> T y;
EP>};

если имеет — то какое правило? о чего зависит?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: шаблон в шаблоне, и реализация вне шаблона
От: Evgeny.Panasyuk Россия  
Дата: 14.11.13 16:12
Оценка: 3 (1) +1
X>и получаю такую ошибку:
X>

X>main.cpp:159:1: error: prototype for 'type<T>::type()' does not match any in class 'type<T>'
X> type<T>::type()
X>main.cpp:141:2: error: candidate is: type<T>::type()
X> type();

X>ЧЯДНТ?

http://coliru.stacked-crooked.com/a/412c0f087204a31f
template<typename T>
struct Foo
{
    template<typename> struct impl;
    T x;
};

template<typename T>
template<typename U>
struct Foo<T>::impl
{
    impl();
    U x;
    T y;
};

template<typename> void type_is();

template<typename T>
template<typename U>
Foo<T>::impl<U>::impl()
{
    type_is<T>();
    type_is<U>();
    type_is<decltype(x)>();
    type_is<decltype(y)>();
}

int main()
{
    Foo<int>::impl<double>{};
}
/**********/
main.cpp:(.text.startup+0x5): undefined reference to `void type_is<int>()'
main.cpp:(.text.startup+0xa): undefined reference to `void type_is<double>()'
main.cpp:(.text.startup+0xf): undefined reference to `void type_is<double>()'
main.cpp:(.text.startup+0x14): undefined reference to `void type_is<int>()'
Re[3]: шаблон в шаблоне, и реализация вне шаблона
От: Evgeny.Panasyuk Россия  
Дата: 14.11.13 16:20
Оценка: 9 (1) +1
Здравствуйте, niXman, Вы писали:

X>вот тут, к примеру, имеет значение порядок записи параметров T и U ?

[...]
X>если имеет — то какое правило? о чего зависит?

Да, имеет — нужно в порядке от внешнего шаблона, к внутреннему:

14.5.2 Member templates
1. A template can be declared within a class or class template; such a template is called a member template. A member template can be defined within or outside its class definition or class template definition. A member template of a class template that is defined outside of its class template definition shall be specified with the template-parameters of the class template followed by the template-parameters of the member template.
[ Example:

template<class T> struct string {
    template<class T2> int compare(const T2&);
    template<class T2> string(const string<T2>& s) { / ... / }
};
template<class T> template<class T2> int string<T>::compare(const T2& s) {
}

—end example ]

Re[4]: шаблон в шаблоне, и реализация вне шаблона
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.11.13 16:25
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

я определенно чего-то не понимаю...
не затруднит тебя показать на этом примере, плиз?:
template<typename T>
struct type {
    template<typename>
    struct impl;

    type();
    ~type();

    void m();

private:
    impl<T> *pimpl;
};

template<typename T>
template<typename A>
struct type<T>::impl {
    impl();

    T t;
    A a;
};
template<typename T>
template<typename A>
type<T>::impl<A>::impl()
{}

template<typename T>
template<typename A>
type<T>::type()
    :pimpl(new type<T>::impl<A>)
{}
template<typename T>
type<T>::~type()
{ delete pimpl; }
template<typename T>
void type<T>::m()
{std::cout << "ping!" << std::endl;}

int main() {
    type<int> t;
    t.m();
}
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[4]: шаблон в шаблоне, и реализация вне шаблона
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.11.13 16:28
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Да, имеет — нужно в порядке от внешнего шаблона, к внутреннему:

EP>

EP>14.5.2 Member templates
EP>1. A template can be declared within a class or class template; such a template is called a member template. A member template can be defined within or outside its class definition or class template definition. A member template of a class template that is defined outside of its class template definition shall be specified with the template-parameters of the class template followed by the template-parameters of the member template.
EP>[ Example:
EP>

EP>template<class T> struct string {
EP>    template<class T2> int compare(const T2&);
EP>    template<class T2> string(const string<T2>& s) { / ... / }
EP>};
EP>template<class T> template<class T2> int string<T>::compare(const T2& s) {
EP>}
EP>

EP>—end example ]

это понял.

но все равно не понимаю, что с моим кодом не так...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[5]: шаблон в шаблоне, и реализация вне шаблона
От: Evgeny.Panasyuk Россия  
Дата: 14.11.13 16:31
Оценка: 3 (1) +1
Здравствуйте, niXman, Вы писали:

X>я определенно чего-то не понимаю...

X>не затруднит тебя показать на этом примере, плиз?:

Конечно не затруднит
http://coliru.stacked-crooked.com/a/e816d3f2ceca53c2
template<typename T>
type<T>::type()
    :pimpl(new type<T>::impl<T>)
{}

Но, лучше внутри type завести typedef для impl<T> (или какие там параметры у него ещё есть), тогда будет проще:
template<typename T>
type<T>::type()
    :pimpl(new type<T>::Impl)
{}
Re[3]: шаблон в шаблоне, и реализация вне шаблона
От: k.o. Россия  
Дата: 14.11.13 16:37
Оценка: +1
Здравствуйте, niXman, Вы писали:

X>Здравствуйте, Evgeny.Panasyuk, Вы писали:


X>по твоему мотиву, пытаюсь сделать так:

  Скрытый текст
X>
X>template<typename T>
X>struct type {
X>    template<typename>
X>    struct impl;

X>    type(); // <<<<<<<<<<<<<<<<<<<<<<<<< 141
X>    ~type();

X>    void m();

X>private:
X>    impl<T> *pimpl;
X>};

X>template<typename T>
X>template<typename A>
X>struct type<T>::impl {
X>    T t;
X>    A a;
X>};

X>template<typename T>
X>template<typename A>
X>type<T>::type() // <<<<<<<<<<<<<<<<<<<<<<< 159
X>    :pimpl(new type<T>::impl<A>)
X>{}
X>

X>и получаю такую ошибку:
X>

X>main.cpp:159:1: error: prototype for 'type<T>::type()' does not match any in class 'type<T>'
X> type<T>::type()
X>main.cpp:141:2: error: candidate is: type<T>::type()
X> type();

X>ЧЯДНТ?

type<T>::type нешаблонный метод шаблонного класса, ему не нужно два раза template указывать:
template<typename T>
type<T>::type()
    :pimpl(new type<T>::impl<???>) // тут нужен какой-нибудь тип
{}
Re: шаблон в шаблоне, и реализация вне шаблона
От: GreyMan  
Дата: 14.11.13 16:40
Оценка:
Наследование не поможет?
template<typename T>
struct type {
    template<class U> struct impl{};
    void m();
    impl<T>* p;
};

template<class T,class U> struct TwoArgImpl: type<T>::template impl<T>{
};
....
type<int> t;
t.p=new TwoArgImpl<int,double>();// обычное приведение потомка к базе))
Re[6]: шаблон в шаблоне, и реализация вне шаблона
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.11.13 16:40
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>template<typename T>

EP>type<T>::type()
EP> :pimpl(new type<T>::impl<T>)
EP>{}
но тут и type и impl специализируются одним параметром, но такое не подходит. impl`у нужна возможность принимать другие параметры, не только T
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[7]: шаблон в шаблоне, и реализация вне шаблона
От: Evgeny.Panasyuk Россия  
Дата: 14.11.13 16:47
Оценка:
Здравствуйте, niXman, Вы писали:

EP>>template<typename T>

EP>>type<T>::type()
EP>> :pimpl(new type<T>::impl<T>)
EP>>{}
X>но тут и type и impl специализируются одним параметром, но такое не подходит. impl`у нужна возможность принимать другие параметры, не только T

Укажи тот параметр, который нужен (это не обязательно T), и будет совместим с:
template<typename T>
struct type {
// ...
    impl<T> *pimpl;
};
В type у тебя фиксированный набор impl<?>.
Re[7]: шаблон в шаблоне, и реализация вне шаблона
От: night beast СССР  
Дата: 14.11.13 16:56
Оценка:
Здравствуйте, niXman, Вы писали:

EP>>template<typename T>

EP>>type<T>::type()
EP>> :pimpl(new type<T>::impl<T>)
EP>>{}
X>но тут и type и impl специализируются одним параметром, но такое не подходит. impl`у нужна возможность принимать другие параметры, не только T

передавай нужный тип шаблонным параметром конструктора, или заводи отдельный метод:
template<typename T>
template<typename U>
type<T>::type ( identity<U> * ) : pimpl(new type<T>::impl<U> ){}

template<typename T>
template<typename U> type<T> type<T>::create( ) { return type<T>( (identity<U>*)0 ); }
Re[8]: шаблон в шаблоне, и реализация вне шаблона
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.11.13 17:00
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Укажи тот параметр, который нужен (это не обязательно T), и будет совместим с:

так я это и пытался сделать, тут:
template<typename T>
template<typename A>
type<T>::impl<A>::impl()
{}

т.е. тут T для type, и A для impl

EP>В type у тебя фиксированный набор impl<?>.

да, не вариадик.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[8]: шаблон в шаблоне, и реализация вне шаблона
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.11.13 17:01
Оценка:
Здравствуйте, night beast, Вы писали:

NB>передавай нужный тип шаблонным параметром конструктора, или заводи отдельный метод:

мне не конструктор impl`а нужно параметризовать, а весь impl.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[9]: шаблон в шаблоне, и реализация вне шаблона
От: night beast СССР  
Дата: 14.11.13 17:06
Оценка:
Здравствуйте, niXman, Вы писали:

NB>>передавай нужный тип шаблонным параметром конструктора, или заводи отдельный метод:

X>мне не конструктор impl`а нужно параметризовать, а весь impl.

давай ты на псевдокоде изобразишь, что хочешь получить, а мы подумаем, как это реализовать.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.