nested template partial specialization
От: frogkiller Россия  
Дата: 03.10.07 05:39
Оценка:
Здравствуйте, не подскажете, где я ошибся? Очень хочется сделать так:
#include <iostream>

struct FirstSelector {};
struct SecondSelector {};

struct Foo {};

template <typename T>
struct Bar
{
       template <typename U>
       struct Nested
       {
              void test();
       };
       Nested<FirstSelector> m_first;
       Nested<SecondSelector> m_second;
       
       void test()
       {
            m_first.test();
            m_second.test();
       }
};

template <> template <typename T>
void Bar<T>::Nested<FirstSelector>::test()
{
     std::cout << "first" << std::endl;
}
template <> template <typename T>
void Bar<T>::Nested<SecondSelector>::test()
{
     std::cout << "second" << std::endl;
}

int main(int argc, char *argv[])
{
    Bar<Foo> bar;
    bar.test();
    
    return 0;
}

Но не работает Что не так?
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re: nested template partial specialization
От: frogkiller Россия  
Дата: 03.10.07 05:54
Оценка:
Нашёл в сети workaround:
#include <iostream>

struct FirstSelector {};
struct SecondSelector {};

struct Foo {};

template <typename T>
struct Bar
{
       template <typename U, typename U2 = void>
       struct Nested;

       template <typename U2>
       struct Nested<FirstSelector, U2>
       {
              void test();
       };
       template <typename U2>
       struct Nested<SecondSelector, U2>
       {
              void test();
       };

       Nested<FirstSelector> m_first;
       Nested<SecondSelector> m_second;
       
       void test()
       {
            m_first.test();
            m_second.test();
       }
};

template <typename T> template <typename U2> 
void Bar<T>::Nested<FirstSelector, U2>::test()
{
     std::cout << "first" << std::endl;
}
template <typename T> template <typename U2> 
void Bar<T>::Nested<SecondSelector, U2>::test()
{
     std::cout << "second" << std::endl;
}

int main(int argc, char *argv[])
{
    Bar<Foo> bar;
    bar.test();
    
    return 0;
}

Но имхо это выглядит довольно криво.
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re: nested template partial specialization
От: _Dreamer Россия  
Дата: 03.10.07 08:09
Оценка:
Здравствуйте, frogkiller, Вы писали:

F>Здравствуйте, не подскажете, где я ошибся? Очень хочется сделать так:

F>Но не работает Что не так?

ну если почему то нельзя сделать специализацию внутри, вот так —
template <typename T>
struct Bar
{
    template <typename U>
    struct Nested
    {
        void test();
    };    

    template <>
    struct Nested<FirstSelector>
    {
        void test() 
        {
            std::cout << "first" << std::endl;
        }
    };    

    template <>
    struct Nested<SecondSelector>
    {
        void test() 
        {
            std::cout << "second" << std::endl;
        }
    };    

    Nested<FirstSelector> m_first;
    Nested<SecondSelector> m_second;

    void test()
    {
        m_first.test();
        m_second.test();
    }
};


то можно наследоваться от базового, и его уже специализировать
template < typename T, typename U >
struct BaseNested
{
    void test();
};

template < typename T >
struct BaseNested<T, FirstSelector>
{
    void test()
    {
        std::cout << "first" << std::endl;
    }
};

template < typename T >
struct BaseNested<T, SecondSelector>
{
    void test()
    {
        std::cout << "second" << std::endl;
    }
};

template <typename T>
struct Bar2
{
    template <typename U>
    struct Nested : BaseNested<T, U>
    {
        
    };                    

    Nested<FirstSelector> m_first;
    Nested<SecondSelector> m_second;

    void test()
    {
        m_first.test();
        m_second.test();
    }
};
Re: nested template partial specialization
От: Константин Л. Франция  
Дата: 03.10.07 09:21
Оценка:
Здравствуйте, frogkiller, Вы писали:

F>Здравствуйте, не подскажете, где я ошибся? Очень хочется сделать так:

F>
[]
F>template <typename T>
F>struct Bar
F>{
F>       template <typename U>
F>       struct Nested
F>       {
F>              void test();
F>       };
F>       Nested<FirstSelector> m_first;
F>       Nested<SecondSelector> m_second;
       
F>       void test()
F>       {
F>            m_first.test();
F>            m_second.test();
F>       }
F>};

[]

F>

F>Но не работает Что не так?

Что это выд.? Что не работает то? Где ошибка и что говорит?
Re[2]: nested template partial specialization
От: frogkiller Россия  
Дата: 03.10.07 10:33
Оценка:
Здравствуйте, _Dreamer, Вы писали:

_D>ну если почему то нельзя сделать специализацию внутри, вот так —

_D>
_D>


"ComeauTest.c", line 12: error: explicit specialization is not allowed in the
current scope
template <>


_D>то можно наследоваться от базового, и его уже специализировать

_D>
_D>


У этого подхода два недостатка:
1. Базовый класс объявлен вне Bar, соответсвенно в нём не определены его (Bar'а) typedef'ы.
2. Вместо уменьшения кода получается его раздутие. Проще тогда уже вообще отказаться от вложенного шаблона и просто сделать два разных класса.

Я же предполагал использовать вот так:
struct Foo
{
    template <typename T>
    struct Test1
    {
        void doPrint() const;
        void Print() const
        {
            doPrint();
        }
    };

    void test()
    {
        Foo::Test1<char> t1;
        Foo::Test1<double> t2;

        t1.Print();
        t2.Print();
    }
};

template <>
void Foo::Test1<char>::doPrint() const
{
    std::cout << "hello" << std::endl;
}
template <>
void Foo::Test1<double>::doPrint() const
{
    std::cout << "preved" << std::endl;
}

int main(int argc, char* argv[])
{
    Foo foo;
    foo.test();

    return 0;
}

Вот этот пример работает. Но если Foo сделать шаблонным, сыпятся ошибки.
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re[2]: nested template partial specialization
От: frogkiller Россия  
Дата: 03.10.07 11:02
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>Что это выд.? Что не работает то? Где ошибка и что говорит?


Comeau C/C++ 4.3.8 (Aug 19 2006 13:36:48) for ONLINE_EVALUATION_Alpha1
Copyright 1988-2006 Comeau Computing. All rights reserved.
MODE:strict errors C++

"ComeauTest.c", line 27: error: nontype "Bar<T>::Nested [with T=T]" is not a
template
void Bar<T>::Nested<FirstSelector>::test()
^

"ComeauTest.c", line 32: error: nontype "Bar<T>::Nested [with T=T]" is not a
template
void Bar<T>::Nested<SecondSelector>::test()
^


MSVC 7.1 тоже не сильно информативную ошибку выдаёт:

NestedTemplates.cpp(35): error C3855: 'Bar<T>::Nested': template parameter 'U' is incompatible with the declaration


При этом Комо хочет, чтобы параметры при специализации шли так:
template <> template <typename T>

а MSVC наоборот:
template <typename T> template <>


Вот я и внепонятках.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re[3]: nested template partial specialization
От: frogkiller Россия  
Дата: 03.10.07 11:51
Оценка:
Здравствуйте, frogkiller, Вы писали:

F>Здравствуйте, Константин Л., Вы писали:


Кстати, если указать компилятору, что это шаблон:
template <> template <typename T>
void Bar<T>::template Nested<FirstSelector>::test()
{
     std::cout << "first" << std::endl;
}
template <> template <typename T>
void Bar<T>::Nested<SecondSelector>::test()
{
     std::cout << "second" << std::endl;
}

то появляется более сранное сообщение:

"ComeauTest.c", line 27: error: partial specialization of nontype
"Bar<T>::Nested<FirstSelector>::test" is not allowed
void Bar<T>::template Nested<FirstSelector>::test()
^

"ComeauTest.c", line 32: error: nontype "Bar<T>::Nested [with T=T]" is not a template,
Should it be XX::nontype "Bar<T>::Nested [with T=T]"?, where XX is some namespace?
Did you #include the right header?
void Bar<T>::Nested<SecondSelector>::test()
^

Я так понимаю, что первое сообщение, говорит, что нельзя делать частичную специализацию не типа. Но я же специализирую как раз тип, а не его метод. Такая же специализация для нешаблонного родительского класса вполне корректна (см. мой пост выше).
А второе сообщение означает, что компилятор не может определить, что Bar<T>::Nested является шаблонным типом, и предполагает, что его полное объявление недоступно. Но это как-то странно.
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re[4]: nested template partial specialization
От: Sergey Россия  
Дата: 03.10.07 12:17
Оценка:
"frogkiller" <51834@users.rsdn.ru> wrote in message news:2679250@news.rsdn.ru...
> Здравствуйте, frogkiller, Вы писали:
>
> F>Здравствуйте, Константин Л., Вы писали:
>
> Кстати, если указать компилятору, что это шаблон:
>
> template <> template <typename T>
> void Bar<T>::template Nested<FirstSelector>::test()
> {
>     std::cout << "first" << std::endl;
> }
> template <> template <typename T>
> void Bar<T>::Nested<SecondSelector>::test()
> {
>     std::cout << "second" << std::endl;
> }
>

> то появляется более сранное сообщение:
>

> "ComeauTest.c", line 27: error: partial specialization of nontype
> "Bar<T>::Nested<FirstSelector>::test" is not allowed
> void Bar<T>::template Nested<FirstSelector>::test()
> ^
>
> "ComeauTest.c", line 32: error: nontype "Bar<T>::Nested [with T=T]" is not a template,
> Should it be XX::nontype "Bar<T>::Nested [with T=T]"?, where XX is some namespace?
> Did you #include the right header?
> void Bar<T>::Nested<SecondSelector>::test()
> ^

> Я так понимаю, что первое сообщение, говорит, что нельзя делать частичную специализацию не типа. Но я же специализирую как раз тип, а не его метод. Такая же специализация для нешаблонного родительского класса вполне корректна (см. мой пост выше).
> А второе сообщение означает, что компилятор не может определить, что Bar<T>::Nested является шаблонным типом, и предполагает, что его полное объявление недоступно. Но это как-то странно.

А чето я не понял, где здесь собственно частичная специализация. По-моему это обычная explicit specialization и подходит под явный запрет из 14.7.3.18.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[5]: nested template partial specialization
От: frogkiller Россия  
Дата: 03.10.07 12:57
Оценка:
Здравствуйте, Sergey, Вы писали:

S>А чето я не понял, где здесь собственно частичная специализация. По-моему это обычная explicit specialization и подходит под явный запрет из 14.7.3.18.


Во! Спасибо. Что-то меня переклинило

А вообще было бы удобно...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Курица — это инструмент, с помощью которого одно яйцо производит другие.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.