【发布时间】:2021-03-30 02:11:32
【问题描述】:
我想用 C++ 编写一个类型安全的函数来组成任意数量的映射。我通过编写一个辅助函数point 来计算组合在某个点的应用——
template <typename K>
const K& point(const K& k) {
return k; // recursive base-case.
}
template<typename K, typename V, typename ... Ts>
auto point(const K& k, const std::map<K, V>& map, Ts... maps) {
return point(map.at(k), maps...);
}
这使得compose 的逻辑简单明了:
template <typename K, typename V, typename ... Ts>
auto compose(const std::map<K, V>& map, Ts... maps) {
using U = typename std::result_of<point(V, Ts...)>::type; // <- problem
std::map<K, U> composition;
for (const auto& [k, v] : map)
composition[k] = point(v, maps...);
return composition;
}
我唯一的问题是推导U,结果映射的值类型。我确信std::result_of 是一种合适的方法,但我通过上面的代码得到error: 'V' does not refer to a value。我也尝试过使用decltype(point<V, Ts...>()),但这给出了error: no matching function for call to 'point'。
示例用法:
std::map<int, std::string> m1;
m1[0] = "a";
m1[1] = "b";
std::map<std::string, float> m2;
m2["a"] = 3.0;
m2["c"] = 4.0;
std::map<float, std::string> m3;
m3[3.0] = "three";
m3[4.0] = "four";
auto composition = compose(m1, m2, m3);
【问题讨论】:
-
“point”的返回值不是一直都是“const K&”吗?如果是这样,您可以避免出现问题。
-
否
point是一个模板函数,它的返回类型取决于它的模板参数。 -
我认为你可以改用
using U = decltype(point(std::declval<V>(), std::decval<Ts>()...));来让它工作 -
感谢@NathanOliver,这行得通!我要花很长时间才能弄清楚...
-
记住还要在
point()的递归版本之前声明递归基础案例。
标签: c++ variadic-templates return-type-deduction