模板参数推导在优化帮助器模板中失败

时间:2014-07-11 12:16:32

标签: c++ templates

我正在研究一个泛型实用程序,用于将符号整数常量转换为字符串,反之亦然。我遇到了一个帮助模板的问题,以优化字符串参数的传递。这个模板的原因是我希望允许用户同时传递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并将其传递给第一个函数吗?

0 个答案:

没有答案