How come I can’t instantiate an object of type Foo with above constructor?
I have a class Bar that uses an internal typedef (as a workaround for “template typedefs”) and intend to use it in a constructor as below (CASE 1).
However, I don’t seem to get it to compile. Is this legal C++?
CASE 2 seems to suggest the problem is related to the typedef in Bar.
How can I define a constructor that will accept std::vectors of objects with the type in Bar?
#include <vector>
#include <iostream>
#include <utility>
template <typename T>
struct Bar
{
typedef std::pair<T, T> type; // or anything else that uses T
};
struct Foo
{
Foo() {}
// CASE 1: doesn't compile
template <typename T> explicit Foo( const std::vector<typename Bar<T>::type>& data )
{
std::cout << "Hello\n";
}
//// CASE 2: compiles, but it's not what I want
//template <typename T> explicit Foo( const std::vector<Bar<T> >& data )
//{
// std::cout << "Hello\n";
//}
};
int main()
{
std::vector<Bar<int>::type> v; // for CASE 1
//std::vector<Bar<int> > v; // for CASE 2
Foo f( v );
return 0;
}
According to paragraph 14.8.2.1 of the C++ standard, when a template parameter is used only in a non-deduced context, the corresponding template argument cannot be deduced:
The definition of nondeduced contexts, as stated in §14.8.2.4:
In
Bar<T>::type,Bar<T>is a nested-name-specifier and hence a non-deduced context, so you must explicitly specify the template argument when calling the constructor…which is not possible (i.e. you cannot writeFoo f<int>(v)).I suppose the compiler cannot deduce the template argument because that would be at least cumbersome, and more probably impossible: imagine Bar is specialized:
Now I have an ambiguity when calling Foo’s constructor with
std::vector<std::pair<int,int> >: should the template argument beintorchar? And even if there was no such ambiguity, you can easily see that the compiler would have to instantiate Bar with potentially any type before finding the instantiation with the correct typedef (well, I’m not so sure above statements are truly relevant since I often find out compilers to be much more smarter than I thought :-)!)