首页 > 解决方案 > 在智能指针中使用模板类和 const 限定进行模板推导

问题描述

假设我有一个模板类,以及一个在指向 const 的共享指针中接受它的函数,使用它的模板参数作为其签名的一部分:

template <class T>
class SomeClass {};

// Doesn't need to modify the SomeClass object.
template <class T>
T DoSomething(std::shared_ptr<const SomeClass<T>>);

在这种情况下,我可以通过显式指定模板参数DoSomething来使用指向非成本的共享指针进行调用:SomeClass

DoSomething<int>(std::make_shared<SomeClass<int>>());

但这在没有明确的情况下是行不通的,因为类型推导失败了。

在这种情况下,如何通过类型推导使函数可调用?显然,我可以编写另一个接受指向非 const 的共享指针的重载,但是需要将这种类型的每个函数定义两次是一件麻烦事。

理想情况下,对于在重载解决时不正确的输入(指向其他事物的共享指针或非共享指针),这将失败。

标签: c++templatessfinaetypetraitstype-deduction

解决方案


一种可能性是使用帮助器检查正确的类型,同时让DoSomething接受任何类型T(并且无法编译错误T):

#include <iostream>
#include <type_traits>
#include <iomanip>
#include <memory>
#include <type_traits>


template <typename T>
struct Foo{};

template <typename T>
struct is_right_type : std::false_type {};

template <typename X>
struct is_right_type<std::shared_ptr<const Foo<X>>> : std::true_type {};

template <class T>
auto DoSomething(T t){
    static_assert(is_right_type<T>::value);
    return 42;
}


int main()
{        
    //DoSomething(42);  // ERROR
    std::shared_ptr<const Foo<int>> x;
    std::shared_ptr<Foo<int>> y;
    DoSomething(x); // OK
    DoSomething(y); // ERROR
}

您可能需要做一些额外的事情才能正确推断出返回类型。


推荐阅读