Специализация шаблона для любого типа указателя - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть следующий класс

class MyClass {
    std::string id;
    int count;

    MyClass (const std::string& id, const int count) :
        id(id), count(count)
    {}
public:
    template<typename T, typename... Args>
    MyClass (const T& t, Args&&... args) : 
        MyClass(t->getId(), std::forward<Args>(args)...)
    {}
};

В моем реальном случае он более сложный и имеет более одной реализации частного конструктора, поэтому шаблон действительно имеет смысл.

У меня также есть несколько классов с getId методом, подобным этому:

class HasId {
    std::string id;

public:
    HasId (const std::string& id) :
        id(id)
    {}

    const std::string& getId () {
        return id;
    }
};

Так что в моем коде я могу сделать это:

auto a = std::make_shared<HasId>("foobar");
MyClass b(a, 42);
HasId c("foobaz");
MyClass d(&c, 265);

Но у меня есть проблема, когда Args... неявно преобразуются в ожидаемые аргументы конструктора, но имеют другой тип. Как это:

auto a = std::make_shared<HasId>("foobar");
MyClass b(a, 42.0);

В этом случае компилятор пытается заменить string и double на шаблонный ctor и, очевидно, терпит неудачу. Я знаю, что могу изменить частные ctors и инициализировать поле id внутри шаблонного ctor, но мне интересно, можно ли указать один шаблон только для типов указателей (std::shared_ptr<T>, T* и т. Д.).

1 Ответ

0 голосов
/ 25 апреля 2018

Вам нужен конструктор шаблона, чтобы участвовать в разрешении перегрузки, только если t->getId() допустимо.Это можно сделать, добавив (фиктивный) параметр шаблона

template<typename T, typename = decltype(std::declval<T&>()->getId()), typename... Args>
MyClass (const T& t, Args&&... args) : 
    MyClass(t->getId(), std::forward<Args>(args)...)
{}

Посмотри вживую

Однако в твоем случае было бы гораздо проще просто

template<typename T>
MyClass (const T& t, int count) : 
    MyClass(t->getId(), count)
{}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...