kmh*_*ann 7 c++ templates constructor typedef typename
为什么我不能用上面的构造函数实例化一个Foo类型的对象?
我有一个使用内部typedef的类Bar(作为"template typedefs"的解决方法),并打算在构造函数中使用它,如下所示(CASE 1).但是,我似乎没有得到它编译.这是合法的C++吗?案例2似乎表明问题与Bar中的typedef有关.
如何定义一个构造函数来接受带有Bar类型的对象的std :: vectors?
#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;
}
Run Code Online (Sandbox Code Playgroud)
Luc*_*lle 10
根据C++标准的第14.8.2.1段,当模板参数仅在非推导的上下文中使用时,不能推导出相应的模板参数:
如果模板参数未在函数模板的任何函数参数中使用,或者仅在非推导的上下文中使用,则无法从函数调用推断出其对应的模板参数,并且必须明确模板参数指定.
非限制上下文的定义,如第14.8.2.4节所述:
非受限的上下文是:
使用qualified-id 指定的类型的嵌套名称说明符.
作为模板id的类型,其中一个或多个模板参数是引用模板参数的表达式.
在Bar<T>::type,Bar<T>是一个嵌套名称说明符,因此是一个非推导的上下文,所以你必须在调用构造函数时显式指定模板参数...这是不可能的(即你不能写Foo f<int>(v)).
我想编译器不能推导出模板参数,因为这至少是麻烦的,而且可能是不可能的:想象Bar是专门的:
template<typename T>
struct Bar
{
typedef std::pair<T,T> type;
};
template<>
struct Bar<char>
{
typedef std::pair<int,int> type;
};
Run Code Online (Sandbox Code Playgroud)
现在,在调用Foo的构造函数时,我有一个歧义std::vector<std::pair<int,int> >:模板参数应该是int还是char?即使没有这种歧义,你也可以很容易地看到编译器在使用正确的typedef找到实例化之前必须实例化任何类型的Bar(好吧,我不太确定上面的语句是真正相关的,因为我经常找出编译器比我想象的要聪明得多:-)!)