为什么不能从 Template::Type 推导出 T?
这段代码有什么问题?
#include <map>
template<typename T>
struct TMap
{
typedef std::map<T, T> Type;
};
template<typename T>
T test(typename TMap<T>::Type &tmap_) { return 0.0; }
int _tmain(int argc, _TCHAR* argv[])
{
TMap<double>::Type tmap;
tmap[1.1] = 5.2;
double d = test(tmap); //Error: could not deduce template argument for T
return 0;
}
What is wrong in this code?
#include <map>
template<typename T>
struct TMap
{
typedef std::map<T, T> Type;
};
template<typename T>
T test(typename TMap<T>::Type &tmap_) { return 0.0; }
int _tmain(int argc, _TCHAR* argv[])
{
TMap<double>::Type tmap;
tmap[1.1] = 5.2;
double d = test(tmap); //Error: could not deduce template argument for T
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是不可演绎的上下文。这就是编译器无法推导模板参数的原因。
试想一下,如果您可能有如下专门的
TMap
:鉴于
TMap::Type
,编译器将如何推导类型SomeType
是std::map
吗?它不能。 不保证您在std::map
中使用的类型也是类型< /em> 在TMap
中。编译器不能做出这种危险的假设。无论如何,type 参数之间可能没有任何关系。另外,您可能将
TMap
的另一个特化定义为:这会使情况变得更糟。现在您拥有以下内容:
TMap::Type
=std::map
。TMap::Type
=std::map
。现在问问自己:给定
TMap::Type
是std::map
,编译器如何知道T
是SomeType
还是OtherType
?它甚至不知道它有多少这样的选择,它也不知道选择本身......我只是为了思想实验而问你(假设它可以知道整套选择)。
That is non-deducible context. That is why the template argument cannot be deduced by the compiler.
Just imagine if you might have specialized
TMap
as follows:How would the compiler deduce the type
SomeType
, given thatTMap<SomeType>::Type
isstd::map<double, double>
? It cannot. It's not guaranteed that the type which you use instd::map
is also the type inTMap
. The compiler cannot make this dangerous assumption. There may not any relation between the type arguments, whatsoever.Also, you might have another specialization of
TMap
defined as:This makes the situation even worse. Now you've the following:
TMap<SomeType>::Type
=std::map<double, double>
.TMap<OtherType>::Type
=std::map<double, double>
.Now ask yourself: given
TMap<T>::Type
isstd::map<double, double>
, how would the compiler know whetherT
isSomeType
orOtherType
? It cannot even know how many such choices it has, neither can it know the choices themselves...I'm just asking you for the sake of thought-experiment (assuming it can know the complete set of choices).
正是编译器错误消息所说的内容:
TMap::Type
,T
不能根据标准。这样做的动机可能不是
技术上可以实现:编译器必须
实例化所有可能的
TMap
以查看是否有一个(并且只有一个)与您传递的类型匹配。并且有一个
无限数量的
TMap
。Exactly what the compiler error message says: in
TMap<T>::Type
,T
is not deduceable according to thestandard. The motivation for this is probably that it isn't
technically possible to implement: the compiler would have to
instantiate all possible
TMap<T>
in order to see if one (andonly one) matched the type you passed. And there is an
infinite number of
TMap<T>
.即使您有:
但在调用 test(tmap) 之前,
您已经声明了
无法使用此信息的原因。 #typedef 不仅仅是简单的字符串替换。
Even you have:
But before you call test(tmap)
You already have it declared as
why this information can not be utilized. #typedef is not just simple string replacement.
我认为“我们不能这样做”的论点是不正确的。
如果我们稍微修改这个例子,编译器就会很高兴地为我们推导出参数。
我没有看到原始示例和我的示例之间有很大差异。这里真正的问题似乎是 C++ 以不同的方式对待 typedef 和类型声明,
这是一件好事吗?
I don't think "we can't do this" argument is correct.
If we slightly modify this example, the compiler is happily deducing arguments for us.
I don't see a huge difference between the original example and mine. The real issue here seems that C++ treats typedefs and type declarations differently
Is this a good thing?