在C ++

时间:2015-06-15 09:30:44

标签: c++ templates pointers c++11

我正在尝试为我的调用函数中作为模板参数指定的指针调用模板函数。我的代码是:

template <>
struct serialize_helper<std::string> {
     // not important code...
    }

};

template <class T>
inline void serializer(const T& obj, StreamType::iterator& res) {

    if(std::is_pointer<T>::value)
    {
        //THIS doesn' work
        serialize_helper<*T>::apply(*obj,res);
    }
    else
        serialize_helper<T>::apply(obj,res);

}

如果我打电话:

std::string test("test");
serializer(test, res);
一切正常。 但我也希望能够使用指针调用序列化程序作为obj:

std::string test* = new std::string("test");
serializer(test, res);

在调用序列化函数之前取消引用指针不是一个可能的选择,请不要这样做。在串行器功能中,它是可能的。

更简短的说明:我想用serializer拨打std::string*,如果我用它指向的std::string来调用它,那就做同样的事情。

3 个答案:

答案 0 :(得分:6)

模板函数的整个主体需要针对它实例化的类型进行编译,无论是否将采用分支。要解决此问题,您可以定义单独的函数,以便T何时是指针,何时不是。

使用SFINAE:

template <class T, std::enable_if_t<std::is_pointer<T>::value>* = nullptr>
inline void serializer(const T& obj, StreamType::iterator& res) {
    serialize_helper<std::remove_pointer_t<T>>::apply(*obj,res);
}

template <class T, std::enable_if_t<!std::is_pointer<T>::value>* = nullptr>
inline void serializer(const T& obj, StreamType::iterator& res) {
    serialize_helper<T>::apply(obj,res);
}

使用tagged-dispatch:

template <class T>
inline void serializer(const T& obj, StreamType::iterator& res, std::true_type) {
    serialize_helper<std::remove_pointer_t<T>>::apply(*obj,res);
}

template <class T>
inline void serializer(const T& obj, StreamType::iterator& res, std::false_type) {
    serialize_helper<T>::apply(obj,res);
}

template <class T>
inline void serializer(const T& obj, StreamType::iterator& res) {
    serializer(obj, res, std::is_pointer<T>());
}

答案 1 :(得分:3)

我会选择像

这样的东西
template <class T>
inline void serializer(const T& obj, StreamType::iterator& res) {
    serialize_helper<T>::apply(obj,res);
}

template<class T>
inline void serializer(T* obj, StreamType::iterator& res) {
    serialize_helper<T>::apply(*obj,res);
}

答案 2 :(得分:0)

您可以std::remove_pointer使用std::enable_if来执行此操作。

template <class T, typename std::enable_if<std::is_pointer<T>::value>::type* = nullptr>
inline void serializer(const T& obj) {
    serialize_helper<typename std::remove_pointer<T>::type>::apply(*obj);
}

template <class T, typename std::enable_if<!std::is_pointer<T>::value>::type* = nullptr>
inline void serializer(const T& obj) {
    serialize_helper<T>::apply(obj);
}

请注意,为了简单起见,我已删除StreamType

live demo