我正在研究一个泛型实用程序,用于将符号整数常量转换为字符串,反之亦然。我遇到了一个帮助模板的问题,以优化字符串参数的传递。这个模板的原因是我希望允许用户同时传递char_t *和string_t(char_t当前只是char的typedef,而string_t是std :: basic_string的typedef)。由于char *是基本类型,因此最好按值传递,因为std :: basic_string<>是一种复杂的类型,最好通过引用传递。模板optimize_insert具有双重目的,即不允许用户传递除(const)char_t *或(const)string_t&之外的任何内容。但也要确保以最有效的方式传递它们。
我对模板参数演绎的理解,我认为是我遇到问题的地方,只是简陋的。但就我从谷歌搜索和阅读标准N3690而言,这个模板应该能够自动推断,而不必明确写出insert<int_t, string_t>(...)
。
有没有人知道为什么clang无法推断出模板参数string_type的类型。确切的错误消息是“候选模板被忽略:无法推断模板参数'string_type'”。
代码如下:
template <typename enum_backing_type>
struct enum_map
{
typedef map_t<int_t, string_t>::type etos_type;
typedef map_t<shash_t, int_t>::type stoe_type;
};
template <typename check_type>
struct optimize_insert;
template <>
struct optimize_insert<string_t>
{
typedef const string_t& type;
};
template <>
struct optimize_insert<char_t*>
{
typedef const char_t* type;
};
template <typename enum_backing_type, typename string_type>
bool_t insert(typename enum_map<enum_backing_type>::etos_type inMap,
enum_backing_type inKey,
typename optimize_insert<string_type>::type inValue)
{
/* see if the entry already exists */
typename enum_map<enum_backing_type>::etos_type::iterator findIter;
/* is there a difference between using std::find and std::map.find()? */
findIter = std::find(inMap.begin(), inMap.end(), inKey);
if (findIter != inMap.end())
return false_t;
/* make pair and insert */
std::pair<enum_backing_type, string_t> entry;
entry = std::make_pair(inKey, string_t(inValue));
inMap.insert(entry);
return true_t;
}
调用代码如下:
enum eTest : schar_t
{
kTest_1,
kTest_2,
kTest_3
};
int main(int argc, char* argv[])
{
enum_map<schar_t>::etos_type etos_map;
enum_map<schar_t>::stoe_type stoe_map;
/* test const char_t* */
insert(etos_map, kTest_1, "kTest_1");
/* test string_t */
string_t test2_string("kTest_2");
insert(etos_map, kTest_2, test2_string);
/* following statement should fail to compile */
insert(etos_map, kTest_2, 1);
for (enum_map<schar_t>::etos_type::iterator printIter = etos_map.begin();
printIter != etos_map.end();
++printIter)
{
std::cout << printIter->second << std::endl;
}
return 0;
}
编辑:所以看来这是一个不可推翻的案例,我只是没有研究到足以找到答案(抱歉)。有没有人知道如何克服这个限制,以便可以有一个string_t和const char_t *的模板版本,以最有效的方式传递参数,而不必重复代码,并做一些const char_t *版本的方案会简单地构造一个string_t并将其传递给第一个函数吗?