plo*_*ong 3 c++ templates boost assign template-argument-deduction
以下玩具程序将一种音乐转换为相应的颜色.它编译并执行正常 - 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;
}
Run Code Online (Sandbox Code Playgroud)
boost::assign::map_list_of
可能不是类型map<K,V>
,而是一些可转换为它的类型.
编译器试图从前两个参数和最后一个参数推导出类型.最后一个没有意义,所以它放弃了.
我们可以阻止对最后一个参数的推论如下:
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;
}
Run Code Online (Sandbox Code Playgroud)
和鲍勃应该是你的叔叔.
在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;
}
Run Code Online (Sandbox Code Playgroud)
这在逻辑上是等价的,但更加丑陋.