0

The following does not compile

#include <iostream>
#include <type_traits>

// forward declaration of a type template
template<class T, class Alloc = std::allocator<T>> class std::vector; 

template<class T>
struct is_vector : std::false_type { };

// using the forward declared type template
template<class T, class Alloc>
struct is_vector<std::vector<T, Alloc>> : std::true_type { };


#include <vector>

int main()
{
    std::cout << is_vector<std::vector<int>>::value << std::endl;
}

I want to make sure that forward declared type templates (above the vector) are actually non useable in specialization contexts and that it's not a faulty implementation to blame. Also why is this happening? I don't want to create an object of type vector<> only use it as a tag to dispatch between specializations; doesn't inclusion of <vector> at the point of instantiation suffice (call site of is_vector<>) ?

Nikos Athanasiou
  • 29,616
  • 15
  • 87
  • 153

1 Answers1

4

Forward-declaring of a standard library container is undefined behavior (if you manage to compile it), so for std::vector you have to #include <vector> before defining is_vector.

For your own types you can do it though:

// forward declaration of a type template
namespace my {
    template<class T, class Alloc> class vector; 
}

template<class T>
struct is_vector : std::false_type { };

// using the forward declared type template
template<class T, class Alloc>
struct is_vector<my::vector<T, Alloc>> : std::true_type { };

namespace my {
    template<class T, class Alloc = std::allocator<T>> class vector {}; 
}
Community
  • 1
  • 1
Anton Savin
  • 40,838
  • 8
  • 54
  • 90
  • I got a variation of the code in question to compile in VS2012 (it fails in gcc), so got confused about the whole situation. Thnx for the info – Nikos Athanasiou Mar 23 '15 at 15:06