指针的部分特化作为函数返回类型

时间:2015-05-13 18:31:22

标签: c++ templates c++11

我有一个模板包装函数,它返回一个这样的值:

template<class T>
T foo(Bar& bar, const char* key) {
    return bar.value<T>(key);
}

但是我想让它处理指针类型有点不同,比如:

template<class T>
T foo(Bar& bar, const char* key) {
    return (T)bar.value<void*>(key);
}

所以我可以这样做:

int x = foo<int>(bar, "x");
Baz* b = foo<Baz*>(bar, "b");

如上所述写它显然会因为多个定义而给我一个错误。有没有其他方法可以做到这一点?我宁愿不为每个使用指针的函数添加一个强制转换。

我尝试过以下方法:

template<class T>
T foo(Bar& bar, const char* key) {
    if(std::is_pointer<T>::value)
        return (T)bar.value<void*>(key);
    else
        return bar.value<T>(key);
}

但是这不起作用,因为涉及QVariants并且它们通过仅使用未知指针类型(bar.value<T>)实例化其模板函数来产生错误。

2 个答案:

答案 0 :(得分:12)

使用标记分派将调用委托给辅助函数,这些函数根据T是否为指针类型执行不同的操作。

namespace detail
{
template<class T>
T foo(Bar& bar, const char* key, std::false_type /*not is_pointer*/) {
    return bar.value<T>(key);
}

template<class T>
T foo(Bar& bar, const char* key, std::true_type /*is_pointer*/) {
    return (T)bar.value<void*>(key);
}
}

template<class T>
T foo(Bar& bar, const char* key) {
    return detail::foo<T>(bar, key, std::is_pointer<T>{});
}

答案 1 :(得分:8)

功能的部分专业化不是语言的一部分。

你可以举例如:

  1. 委托一些课程模板。类模板可以部分专用。
  2. 使用SFINAE。

    template<class T>
    typename std::enable_if<std::is_pointer<T>::value, T>::type
    foo(Bar& bar, const char* key) {return (T)bar.value<void*>(key);}
    
    template<class T>
    typename std::enable_if<!std::is_pointer<T>::value, T>::type
    foo(Bar& bar, const char* key) {return bar.value<T>(key);}