шаблон шаблона возвращаемого типа из функции-члена

Как я могу вернуть любой контейнер целых чисел из функции-члена? В следующем коде я пробовал множество перестановок между двумя тестовыми классами, но, похоже, ничего не компилируется с использованием g ++ - 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 и компилироваться, только если int является содержащимся типом. В других случаях также было бы неплохо распечатать читаемую ошибку пользователю, но я предполагаю, что для этого потребуется либо boost, либо std static_assert (). Спасибо!

ИЗМЕНИТЬ 1

К сожалению, версия с двумя параметрами шаблона работает только для нескольких контейнеров 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;
}

но следующая версия С ++ 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;
}

person user1226313    schedule 20.01.2014    source источник


Ответы (2)


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

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

и .. у вас test структура два ??

person ikh    schedule 20.01.2014
comment
std::vector не тип - person tumdum; 20.01.2014

Одна из ваших проблем заключается в том, что std::vector принимает 2 параметра шаблона (T и распределитель)

Таким образом, следующее может помочь вам, если вы хотите использовать классы шаблонов:

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;
}
person Jarod42    schedule 20.01.2014