【发布时间】:2014-04-16 20:15:13
【问题描述】:
我的标题可能是错误的 - 如果是这样,请纠正我,但在某些时候我很难跟踪我实际想要实现的元目标;)
我有一个这样的类函数模板:
template<template<typename...> class MapType>
Expression Expression::substitute(MapType<std::string, Expression> const& identifierToExpressionMap) const {
return SubstitutionVisitor<MapType>(identifierToExpressionMap).substitute(something);
}
重要的部分是 MapType。这个想法是允许随意插入std::map 或std::unordered_map。使用 GCC 和 Clang,这是可行的,但 Visual Studio 2013 会引发编译错误:
error C2664: 'Expression Expression::substitute<:map>(const MapType &) const' : 无法将参数 1 从 'std::map<:string>,std::allocator<:pair _kty>>>' 转换为 'const std::地图 &' 1> 与 1> [ 1> MapType=std::map 1>] 1> 和 1> [ 1> _Kty=std::字符串 1> , _Ty=表达式 1>] 1> 原因:无法从 'std::map<:string>,std::allocator<:pair _kty>>>' 转换为 'const std ::地图' 1> 与 1> [ 1> _Kty=std::字符串 1> , _Ty=表达式 1>] 1> 没有可以执行此转换的用户定义转换运算符,或者无法调用该运算符
MSVC 好像没有把MapType 和<std::string, Expression> 作为一个类型放在一起,我是不是漏掉了什么?
所以我的问题是
- 这是否可能,只是 MSVC 中的一个错误,或者
- 有没有更简单的方法来做到这一点。请记住,还有许多其他类接收
MapType参数并使用不同的键/值类型实例化它们自己的版本。
【问题讨论】:
-
当 MSVC 不同意 GCC 和 Clang 时,这是 MSVC 中的一个错误。
-
不幸的是,我现在没有 VS2013 可以测试,但由于回复不多,因此您可以测试以下内容:充实函数替代上的参数,使其具有 2 个默认参数地图的模板(std::less 和 std::allocator)。然后让substitute 的调用者尝试传入一个指定了所有模板参数的映射(即:它具有std::less 和std::allocator)。这里的测试是看如果所有模板参数在每一步都显式存在,VS是否处理得更好。
-
@qeadz 但是 unordered_map 的模板参数比 map 多 - 我可以 not 传递 std::map 并将所有参数指定为替换,因为它不再是模板并且我在类中需要不同的键/值类型 - 也许我不明白你的建议......?
-
@qeadz 我想你提到了一个重要的问题:
std::map类模板实际上有四个模板参数,所以当用作模板时,它应该需要 template-argument 所有四个模板参数来实例化(因为默认参数没有传递给模板模板参数)。然而,一些例子用 clang++ 和 g++ 编译,不知道为什么。 -
哇...这似乎是一个悬而未决的问题:open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#150
标签: c++ templates c++11 variadic-templates