Template deduction with templated class and const-qualification in smart pointers

230 views Asked by At

Let's say I've got a templated class, and a function that accepts it in a shared pointer to const, using its template parameter as part of its signature:

template <class T>
class SomeClass {};

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

In this case I can call DoSomething using a shared pointer to non-cost SomeClass by explicitly specifying the template parameter:

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

But this doesn't work without being explicit, because type deduction fails.

How can I make the function callable with type deduction in this case? Obviously I could write another overload that accepted a shared pointer to non-const, but it's a drag to need to define every function of this type twice.

Ideally this would fail for inputs that aren't correct (shared pointers to other things, or non-shared pointers) at overload resolution time.

1

There are 1 answers

0
463035818_is_not_an_ai On

One possibility is to use a helper to check for the right type while letting DoSomething accept any T (and fail to compile for the wrong 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
}

You'll might need to do something extra to get the return type correctly deduced.