2014-01-20 3 views
0

Как я могу вернуть любой контейнер из int из функции-члена? В следующем коде я попытался maany перестановки между двумя тестовыми классами, но ничего, кажется, компилировать с помощью г ++ - 4.8.2:шаблон шаблон возвращаемый тип от функции-члена

#include "vector" 

struct test { 
    template<class Container> Container<int> ret() { 
     return Container<int>(); 
    } 
}; 

struct test { 
    template< 
     template<class Int> class Container, 
     class Int 
    > typename Container<Int> ret() { 
     return Container<Int>(); 
    } 
}; 

int main() { 
    std::vector<int> v = test().ret<std::vector<int> >(); 
    return 0; 
} 

В идеале программа должна быть C++ 03 и компилировать только если ИНТ является . Печатать читаемую ошибку для пользователя в других случаях также было бы неплохо, но я предполагаю, что для этого потребуется либо boost, либо std static_assert(). Благодаря!

EDIT 1

К сожалению, версия параметров 2 шаблон работает только для нескольких StD контейнеров, Закомментированный из них вызывают ошибку компиляции, поскольку они требуют различных параметров шаблона:

struct test { 
    template< 
     template<class, class> class Container 
    > Container<int, std::allocator<int> > ret() { 
     return Container<int, std::allocator<int> >(); 
    } 
}; 

int main() { 
    std::vector<int> v = test().ret<std::vector>(); 
    std::list<int> l = test().ret<std::list>(); 
    //std::set<int> se = test().ret<std::set>(); 
    std::deque<int> d = test().ret<std::deque>(); 
    //std::stack<int> st = test().ret<std::stack>(); 
    //std::queue<int> q = test().ret<std::queue>(); 
    //std::priority_queue<int> p = test().ret<std::priority_queue>(); 
    return 0; 
} 

но следующая версия C++ 11, по-видимому, работает для каждого контейнера:

struct test { 
    template< 
     template<class, class...> class Container, 
     class... Container_Params 
    > Container<int, Container_Params... > ret() { 
     return Container<int, Container_Params... >(); 
    } 
}; 

int main() { 
    auto v = test().ret<std::vector>(); 
    auto l = test().ret<std::list>(); 
    auto se = test().ret<std::set>(); 
    auto d = test().ret<std::deque>(); 
    auto st = test().ret<std::stack>(); 
    auto q = test().ret<std::queue>(); 
    auto p = test().ret<std::priority_queue>(); 
    auto us = test().ret<boost::unordered_set>(); 
    return 0; 
} 

ответ

0
test().ret<std::vector, int>(); 

Я думаю, что это правильно

и .. ваш test структура - это два ??

+0

'std :: vector' is no t тип – tumdum

0
template<bool _Test, class _Ty = void> 
struct enable_if 
{}; 

template<class _Ty> 
struct enable_if<true, _Ty> 
{ typedef _Ty type; }; 

template < typename _Type > 
struct is_int_container { static const bool value = false; }; 

template < typename _Alloc > 
struct is_int_container < std::vector < int, _Alloc > > { static const bool value = true; }; 

template < typename _Alloc > 
struct is_int_container < std::list < int, _Alloc > > { static const bool value = true; }; 

template < typename _Equal, typename _Alloc > 
struct is_int_container < std::set < int, _Equal, _Alloc > > { static const bool value = true; }; 

// Add any required container support 

struct test 
{ 
    template< typename _Type> 
    typename enable_if < is_int_container <_Type> ::value, _Type > ::type 
    ret() 
    { 
     return _Type(); 
    } 
}; 

int main(int agrc, char *argv[]) 
{ 
    test test_; 

    test_.ret<std::vector<int>>(); 
    test_.ret<std::set<int>>(); 
    test_.ret<std::vector<double>>(); // <- compilator error 

    return 0; 
} 
0

Одна из вашей проблемы в том, что std::vector занимает 2 шаблонов параметров (T и Allocator)

Так вам может помочь, если вы хотите принять шаблонные классы:

struct test { 
    template<template<typename, typename> class Container> 
    Container<int, std::allocator<int>> ret() { 
     return Container<int, std::allocator<int>>(); 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    std::vector<int> v = test().ret<std::vector>(); 
    return 0; 
} 

Альтернативой, если вы используете класс, является использование SFINAE как:

template <typename Container, typename T> 
struct is_container_of : 
    std::conditional<std::is_same< 
      typename std::decay<decltype(*std::begin(std::declval<Container>()))>::type, 
      T>::value, 
      std::true_type, std::false_type>::type {}; 

struct test { 
    template<class Container> 
    typename std::enable_if<is_container_of<Container, int>::value, Container>::type 
    ret() { 
     return Container(); 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    auto v = test().ret<std::vector<int>>(); 
    return 0; 
} 
Смежные вопросы