为什么在将模板参数用作另一个模板的模板参数时,不能推导出模板参数?

Joh*_*nas 51 c++ parameters templates

这段代码有什么问题?

#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;
}
Run Code Online (Sandbox Code Playgroud)

Naw*_*waz 82

那是不可导出的背景.这就是编译器无法推导出模板参数的原因.

想象一下,如果你可能有TMap如下专业:

template <>
struct TMap<SomeType>
{
    typedef std::map <double, double> Type;
};
Run Code Online (Sandbox Code Playgroud)

如何将编译器推断类型SomeType,因为TMap<SomeType>::Typestd::map<double, double>?这不可以.它没有保证的类型,你在使用std::map也是类型TMap.编译器无法做出这种危险的假设.类型参数之间可能没有任何关系.

此外,您可能还有另一个TMap定义为:

template <>
struct TMap<OtherType>
{
    typedef std::map <double, double> Type;
};
Run Code Online (Sandbox Code Playgroud)

这使情况更糟.现在你有了以下内容:

  • TMap<SomeType>::Type = std::map<double, double>.
  • TMap<OtherType>::Type= std::map<double, double>.

现在问问自己:给定的TMap<T>::Typestd::map<double, double>,编译器如何知道TSomeType或是OtherType?它甚至不知道它有多少这样的选择,它也不知道自己的选择 ......

我只是为了思考实验而问你(假设它可以知道完整的选择).

  • 精湛的答案.这个问题一再惹恼我,我花了很长时间才明白为什么不可能推断出背景.你的简短例子很好地说明了 (10认同)
  • 这本质上是一个反函数问题:给定一个输出值,您要求输入该函数获取该值的输入点.但是,功能一般不可逆,所以除非你要求你的功能是可逆的,否则问题甚至不存在.在模板场景中,相应的要求是所有模板都具有全局唯一的成员名称; C++没有要求的要求. (6认同)
  • 所以我要写:double d = test <double>(tmap)? (2认同)