Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
SP_root
0 / 0 / 0
Регистрация: 18.11.2014
Сообщений: 28
1

Возврат объекта шаблонного типа от типа Type из специализации шаблона метода от того же типа

22.03.2016, 21:40. Просмотров 562. Ответов 5

Доброго времени суток, пишу класс содержащий несколько std::set от разных типов, нужно сделать метод возвращающий указатель на нужное std::set, в зависимости от того какой тип был подан в шаблон, хочу это реализовать специализацией шаблонов, в черновиках стандарта похожего не нашел.

Класс с шаблоном метода:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef std::set<FrameSelection*> FrameSet;
typedef std::set<Foo*> FooSet;
 
class SelectionManager {
protected:
    Project* current_project_;
    FrameSet   frames_;
    FooSet      foo_;
...
public:
    template < typename TContextRepresented >
        std::set<TContextRepresented*> *
          getSelectionSetPtr() { return 0; }
...
};
специализация шаблона для типа FrameSet

C++
1
2
3
4
5
template <> inline std::set<FrameSelection*>*
    SelectionManager::getSelectionPtr
                        < std::set, FrameSelection >() {
        return &frames_;
    }
заметим, что специализация шаблона для типа FrameSet, в файле .cpp у меня обьявляется как inline, но возвращает 0, видимо из за того что это не работает, если определять специализацию в хидере в теле класса, то вылетают ошибки.

Возможнно ли вообще такое? Где об этом почитать? Если в черновиках стандарта и гугле не нашел? Или же примера кода будет достаточно.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.03.2016, 21:40
Ответы с готовыми решениями:

Явная специализация метода для типа шаблонного класса
Добрый вечер, уважаемые знатоки! :) Хочу задать вопрос по созданию шаблонов. В общем, пусть у меня...

Можно ли присвоить объекту основного типа значение объекта пользовательского типа?
Правильно ли я понимаю, что SomeClass obj; int x = obj; или SomeClass obj; int x = 5 +...

Передать массив элементов(типа int) объекта, в функцию из массивов(типа int)
Представьте такую ситуацию. Есть у вас массив чисел: Mass И вы хотите передать его в функцию. Я...

Создать переменную типа, хранящегося в переменной типа Type
Здравствуйте. Гугл не помог, потому обращаюсь за помощью к вам. Пишу загрузку (не важно чего) из...

Как вызвать из одного класса (для метода типа void) метод типа boolean другого класса?
ребят, только учусь и конечно, вопросов возникает много. ситуация вот в чем. есть массив. я должна...

5
DrOffset
9770 / 5296 / 1295
Регистрация: 30.01.2014
Сообщений: 8,542
23.03.2016, 10:29 2
SP_root, невнимательноть банальная. У тебя специализации и основная шаблонная функция имеют разные имена.
Таким образом у тебя есть два пути:
* Оставлять специализации в cpp (при этом обязательно убрать у них inline).
* Вынести их в заголовочный файл, inline при этом необходимо оставить.

Пример:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <set>
#include <cassert>
 
class A;
class B;
class C;
 
 
typedef std::set<A*> ASet;
typedef std::set<B*> BSet;
typedef std::set<C*> CSet;
 
class SelectionManager
{
protected:
    ASet   as_;
    BSet   bs_;
    CSet   cs_;
 
public:
    template <typename TContextRepresented>
    std::set<TContextRepresented *> * getSelectionPtr()
    {
        return 0;
    }
};
 
template <>
inline ASet * SelectionManager::getSelectionPtr()
{
    return &as_;
}
template <>
inline BSet * SelectionManager::getSelectionPtr()
{
    return &bs_;
}
template <>
inline CSet * SelectionManager::getSelectionPtr()
{
    return &cs_;
}
 
int main()
{
    SelectionManager sm;
 
    ASet * pas = sm.getSelectionPtr<A>();
    assert(pas != 0);
 
    BSet * pbs = sm.getSelectionPtr<B>();
    assert(pbs != 0);
 
    CSet * pcs = sm.getSelectionPtr<C>();
    assert(pcs != 0);
 
    std::set<int*> * pds = sm.getSelectionPtr<int>();
    assert(pds == 0);
}
Онлайн тест: http://rextester.com/XEUQ44982

Почитать можно в книге "Шаблоны C++. Справочник разработчика."
0
SP_root
0 / 0 / 0
Регистрация: 18.11.2014
Сообщений: 28
23.03.2016, 20:40  [ТС] 3
Решение немного упрощенной задачи, под OpenSuse 13.2 все компилируется и работает, под Windows 7, нет, а программу надо делать под Windows, inline не нужен. Если определить как inline, то видимо вызовется не специализрованный метод.

под мастдаем дает ошибку:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
debug/templatetest.o: In function `ZN12TemplateTest13getContainterIP5QRectEEPSt3setIT_St4lessIS4_ESaIS4_EEv':
C:\Files\qt\templates-build-desktop-Qt_4_8_6__4_8_6_________/../templates/templatetest.cpp:24: multiple definition of `std::set<QRect*, std::less<QRect*>, std::allocator<QRect*> >* TemplateTest::getContainter<QRect*>()'
debug/main.o:C:\Files\qt\templates-build-desktop-Qt_4_8_6__4_8_6_________/../templates/templatetest.h:24: first defined here
debug/templatetest.o: In function `ZN12TemplateTest13getContainterI7QStringEEPSt3setIT_St4lessIS3_ESaIS3_EEv':
C:\Files\qt\templates-build-desktop-Qt_4_8_6__4_8_6_________/../templates/templatetest.cpp:33: multiple definition of `std::set<QString, std::less<QString>, std::allocator<QString> >* TemplateTest::getContainter<QString>()'
debug/main.o:C:\Files\qt\templates-build-desktop-Qt_4_8_6__4_8_6_________/../templates/main.cpp:6: first defined here
debug/templatetest.o: In function `ZN12TemplateTest13getContainterIP7QStringEEPSt3setIT_St4lessIS4_ESaIS4_EEv':
C:\Files\qt\templates-build-desktop-Qt_4_8_6__4_8_6_________/../templates/templatetest.cpp:37: multiple definition of `std::set<QString*, std::less<QString*>, std::allocator<QString*> >* TemplateTest::getContainter<QString*>()'
debug/main.o:C:\Files\qt\templates-build-desktop-Qt_4_8_6__4_8_6_________/../templates/main.cpp:6: first defined here
collect2.exe: error: ld returned 1 exit status
Makefile.Debug:76: recipe for target 'debug\templ
Bash
1
2
3
4
5
6
7
mingw32-version
GNU Make 3.82.90
Built for i686-pc-mingw32
Copyright (C) 1988-2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <[url]http://gnu[/url]
This is free software: you are free to change and redi
There is NO WARRANTY, to the extent permitted by law.
0
DrOffset
9770 / 5296 / 1295
Регистрация: 30.01.2014
Сообщений: 8,542
23.03.2016, 20:57 4
Цитата Сообщение от SP_root Посмотреть сообщение
inline не нужен. Если определить как inline, то видимо вызовется не специализрованный метод.
Цитирую себя:
Цитата Сообщение от DrOffset Посмотреть сообщение
Вынести их в заголовочный файл, inline при этом необходимо оставить.
Твой проект успешно собирается (я проверил), если вынести специализации в заголовочный файл. Естественно из cpp их надо убрать.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
typedef std::set<QRect*, std::less<QRect*>, std::allocator<QRect*> >
        QRectPtrSet;
 
class TemplateTest
{
private:
    QRectPtrSet rects_;
    std::set<QString> strings_;
    std::set<QString*> strings_ptr_;
public:
    template <typename T> std::set<
                            T, std::less<T>,
                            std::allocator<T>
                          > *
        getContainter() { return 0; }
    TemplateTest();
    ~TemplateTest();
};
 
template <> inline QRectPtrSet*
     TemplateTest::getContainter()
        { return &rects_; }
 
template <> inline std::set<QString>*
     TemplateTest::getContainter()
        { return &strings_; }
 
template <> inline std::set<QString*>*
     TemplateTest::getContainter()
        { return &strings_ptr_; }
0
SP_root
0 / 0 / 0
Регистрация: 18.11.2014
Сообщений: 28
24.03.2016, 08:30  [ТС] 5
Вечером проверю, Можно версию вашего компилятора на всякий пожарный?
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4848 / 2492 / 696
Регистрация: 18.10.2014
Сообщений: 4,326
24.03.2016, 09:38 6
В определении класса шаблонный метод getSelectionSetPtr зависит от одного шаблонного параметра TContextRepresented. В специализации же этого метода вы вдруг указали два специализированных аргумента < std::set, FrameSelection >. Почему два? Откуда вдруг взялся второй? Неудивительно, что это не компилируется.
0
24.03.2016, 09:38
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.03.2016, 09:38

Как можно определить что-то типа процедурного типа или классового метода (как в Delphi)?
Подскажите: как можно определить что-то типо процедурного типа или классового метода(как в...

Условие типа if( масив типа char[x] [y] != переменная типа char) не срабатывает
Создал функцию ChangeWay(). Все, кроме if(map !=ar) (обе переменные типа char) работает...

Использование шаблонного типа в shared_ptr
Здравствуйте, я решил поупражняться на С++ и написать свой двунаправленный список: Node.h...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru