为什么模板参数推导不起作用?
Why isn't template argument deduction working?
下面的玩具程序将一种类型的音乐转换为相应的颜色。它编译和执行得很好——COUNTRY
的转换如预期的那样失败,conversion()
函数返回默认值WHITE
。但是,如果删除模板参数<MUSIC, COLOR>
,则模板参数推导无法识别要使用的类型。我怎样才能让扣款生效?
#include <map>
#include <iostream>
#include "boost/assign.hpp"
template<typename Key, typename T>
T convert(const Key &k, const T &d, const std::map<Key, T> &m) {
typename std::map<Key, T>::const_iterator it = m.find(k);
return it == m.end() ? d : it->second;
}
enum MUSIC { ROCK, RAP, EDM, COUNTRY };
enum COLOR { RED, BLUE, ORANGE, WHITE };
int main()
{
COLOR c = convert<MUSIC, COLOR>(COUNTRY, WHITE,
boost::assign::map_list_of (RAP, RED) (EDM, BLUE) (ROCK, RED));
std::cout << c << std::endl;
}
boost::assign::map_list_of
可能不是map<K,V>
类型,而是可以转换为它的某种类型。
编译器正试图从前2个参数和最后1个参数中推导出类型。最后一个1没有意义,所以它放弃了。
我们可以阻止对最后一个参数的推导,如下所示:
template<class T>struct tag{using type=T;};
template<class Tag>using type_t=typename Tag::type;
template<class T>using block_deduction=type_t<tag<T>>;
template<typename Key, typename T>
T convert(const Key &k, const T &d, const block_deduction<std::map<Key, T>> &m) {
typename std::map<Key, T>::const_iterator it = m.find(k);
return it == m.end() ? d : it->second;
}
鲍勃应该是你的叔叔。
在C++03:中
template<class T>struct no_deduction{typedef T type;};
template<typename Key, typename T>
T convert(const Key &k, const T &d, const typename no_deduction<std::map<Key, T>>::type &m) {
typename std::map<Key, T>::const_iterator it = m.find(k);
return it == m.end() ? d : it->second;
}
这在逻辑上是等价的,但更丑陋。
boost::assign::map_list_of
不是std::map
,但它可以转换为1。如果你不想改变你的功能,你可以改变你创建地图的方式。有了C++,我们现在有了可用于构造对象的初始值设定项列表。使用初始值设定项列表,我们可以更改
COLOR c = convert<MUSIC, COLOR>(COUNTRY, WHITE,
boost::assign::map_list_of (RAP, RED) (EDM, BLUE) (ROCK, RED));
至
COLOR c = convert(COUNTRY, WHITE, {{RAP, RED},{EDM, BLUE},{ROCK, RED}});
这将使用相同的结果,并允许模板类型的推导工作。
实例
相关文章:
- 带有指定长度字符* 参数的 std::regex_search 在 VS2017 中不起作用?
- 我正在开发服务器,ip作为参数传递不起作用
- G++ C++17 类模板参数推导在非常特殊的情况下不起作用
- 类中的虚拟布尔函数参数不起作用
- 模板 ctor 类型推导不起作用(没有匹配的构造函数用于初始化 ...)与函数<>参数
- 我的代码在作为参数传入 .begin() 时不起作用,但在我将 .begin() 转换为迭代器后工作
- 为什么重载运算符>在参数声明 const 时不起作用?
- 为什么当我提供一些模板参数时,C++17 模板类推导不起作用?
- 为什么static_assert在带有 const 参数的成员函数中不起作用?
- ConvertToReferencePoint 方法不起作用,获取作业参数的 NULL (HyperV 2016)
- 线程函数参数的前向声明不起作用
- 模板参数类型推导在函数对象中不起作用
- 将参考类型作为嵌套模板结构中的模板参数作为模板参数不起作用
- 为什么参数推断在此模板模板参数中不起作用
- C++ 数组参数不起作用
- 带有 3 个参数的冲刺不起作用
- 模板参数在具有相同数据类型的单个类型名的构造函数中不起作用
- 像在 Python 中一样C++循环中的参数解析。为什么不起作用?
- C 类是功能不起作用的参数
- 为什么在参数输入之前将计算放置在代码中时,计算不起作用