简体   繁体   English

在C ++中,调用模板函数以从模板函数中获取指针的值

[英]Call template function for the value of a pointer out of a template function, in C++

I am trying to call a template function for the pointer that was given as template parameter in my calling function. 我正在尝试为在调用函数中作为模板参数给出的指针调用模板函数。 My code is: 我的代码是:

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);

}

If I call: 如果我打电话给:

std::string test("test");
serializer(test, res);

everything works fine. 一切正常。 But I want also to be able to call the serializer with a pointer as obj: 但我也希望能够使用obj指针来调用序列化程序:

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

Dereferencing the pointer before calling the serializer function is not a possible option, please do not propose that. 在调用序列化函数之前,请先取消对指针的引用,请不要提出该建议。 Inside the serializer function it is possible. 在串行器功能内部,这是可能的。

Shorter description: I want to call serializer with a std::string* and have that do the same thing has if I'd called it with the std::string it points to. 简短说明:我想使用std::string*调用serializer ,并且如果我使用它指向的std::string调用,则具有相同的功能。

The whole body of your template function needs to compile for the types it's instantiated with, regardless of whether or not a branch will ever be taken. 模板函数的整个主体都需要为其实例化的类型进行编译,而不管是否将采用分支。 To get around this issue, you can define separate functions for when T is a pointer and when it's not. 要解决此问题,可以为何时T是指针,何时不是T定义单独的函数。

Using SFINAE: 使用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);
}

Using 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>());
}

I'd go with something like 我会喜欢这样的东西

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);
}

You could use std::remove_pointer to do that with std::enable_if . 您可以使用std::remove_pointerstd::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);
}

Note that I've removed the StreamType for simplicity. 请注意,为简单起见,我删除了StreamType

live demo 现场演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM