Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error passing std::vector as a template template parameter - works in GCC, fails in MSVC

Tags:

c++

templates

The following code

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <deque>
#include <functional>

#define BEGIN_TO_END(container) container.begin(), container.end()

template <template<typename...> class OutputContainerType, class InContainer>
OutputContainerType<typename InContainer::value_type> convertContainer(const InContainer& in)
{
    OutputContainerType<typename InContainer::value_type> result;
    std::transform(BEGIN_TO_END(in), std::back_inserter(result), [](typename InContainer::value_type value) {return value;});
    return result;
}

int main() {
    std::deque<int> d {1, 2, 3};
    const auto v = convertContainer<std::vector>(d);
    std::cout << v.size() << std::endl;
}

works fine with GCC (link). However, it doesn't compile with MSVC 2013 (12.0) with the error: 'std::vector' : class has no constructors (can be tested here, select 12.0 compiler version). What's the problem here, and how can I fix it?

like image 648
Violet Giraffe Avatar asked Mar 17 '15 11:03

Violet Giraffe


Video Answer


1 Answers

The code:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <deque>
#include <functional>

#define BEGIN_TO_END(container) container.begin(), container.end()

template <template<typename T, typename T2> class OutputContainerType, class InContainer>
OutputContainerType<typename InContainer::value_type, std::allocator<typename InContainer::value_type>> convertContainer(const InContainer& in)
{
    OutputContainerType<typename InContainer::value_type, std::allocator<typename InContainer::value_type>> result;
    std::transform(BEGIN_TO_END(in), std::back_inserter(result), [](typename InContainer::value_type value) {return value;});
    return result;
}

int main() {
    std::deque<int> d {1, 2, 3};
    const auto v = convertContainer<std::vector>(d);
    std::cout << v.size() << std::endl;
}

Worked. The problem is then with variadic number of template parameters here...

EDITED: Actually not with the variadic number of template parameters as I can even compile it with the

template <template<typename...> class OutputContainerType, class InContainer>

so the MSVC compiler needs explicitly given each type of the template.

like image 195
W.F. Avatar answered Oct 19 '22 20:10

W.F.