模板推断与智能指针

Dan*_*anu 3 c++ templates pointers

我的代码看起来像这样:

#include <iostream>
#include <memory>

using namespace std;

class myClass
{
    int a;
};

template <typename T, template<typename ValueType> class SmartPtr> // (1)
void myFunction(const void *pointer, SmartPtr<T>& pointer2)
{
    cout<<"with template"<<endl;
}

void myFunction(const void *pointer, unique_ptr<myClass>& pointer2)
{
    cout<<"without template "<< *(static_cast<const int*>(pointer))<<endl;
}

int main()
{
    int* a = new int(5);
    unique_ptr<myClass> myUniquePtr(new myClass);
    shared_ptr<myClass> mySharedPtr(new myClass);

    myFunction(static_cast<const void*>(a), myUniquePtr); // (2)
    myFunction<int, unique_ptr<myClass> >(static_cast<const void*>(a), myUniquePtr); // (3)
    myFunction<int, shared_ptr<myClass> >(static_cast<const void*>(a), mySharedPtr); // (4)

    delete a;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在(2)中调用'myFunction'是可以的 - 它在没有模板的情况下调用'myFunction'.但是在(3)和(4)中编译器不能推导出模板参数.它会产生错误:

no matching function for call to ‘myFunction(const void*, std::unique_ptr<myClass>&)'no matching function for call to ‘myFunction(const void*, std::shared_ptr<myClass>&)' 分别.

问题是如何在(1)中更改模板的第二个参数,以便我可以使用任意智能指针实例化模板?我想省略ValueType并使用T.

cdh*_*wie 8

不需要有两个模板参数,这将导致使用自定义分配器的智能指针出现问题.只有一个模板参数:智能指针的类型.

template <typename T>
void myFunction(const void *pointer, T & pointer2)
{
}
Run Code Online (Sandbox Code Playgroud)

所以T是智能指针类型.如果您需要访问托管对象的类型(myClass在本例中),您可以使用typename std::pointer_traits<T>::element_type.

template <typename T>
void myFunction(const void *pointer, T & pointer2)
{
    typedef typename std::pointer_traits<T>::element_type obj_type;

    obj_type & o = *pointer2;
}
Run Code Online (Sandbox Code Playgroud)

(当然,如果你使用的是C++ 11,你也可以使用它decltype(*pointer2)甚至auto.)

使用这种方法,您甚至可以使用原始指针T,假设您的逻辑都不依赖于它们是智能指针.


作为旁注,您的调用可能会失败,因为您提供的intT模板参数,这没有任何意义; 你应该在myClass那里使用.