вывод спецификации шаблона на основе аргументов конструктора - PullRequest
0 голосов
/ 09 апреля 2020

Я пытаюсь предоставить небольшую специализацию класса, когда 2 предоставленных типа похожи, и я достиг следующего кода, который работает:

template<typename Fn, typename U, typename V>
class K {
    public:
    K(Fn f, U u, V v) : u_(u), v_(v) {
        std::cout << "2 args\n";
    }

    private:
    V v_;
    U u_;
};

template<typename Fn, typename U>
class K<Fn, U, U> {
    public:
    K(Fn f, U u) : u_(u) {
        std::cout << "1 args\n";
    }

    private:
    U u_;
};

void koo(int i, double d) {}
void moo(int i) {}

int main() {
    K(koo, 3, 5.6);
    K<decltype(moo), int, int>(moo, 3);
}

Моя единственная проблема заключается в том, что для выбора специализации я должен предоставить <decltype(moo), int, int> вручную или специализация не будет выбрана. Интересно, можно ли выбрать эту специализацию на основе одного аргумента конструктора, чтобы K(moo,3); тоже работал. Есть идеи?

Ответы [ 2 ]

2 голосов
/ 09 апреля 2020

В C ++ 17 предоставьте руководство по удержанию для CTAD :

template <typename Fn, typename U> K(Fn, U) -> K<Fn, U, U>;

Демо

1 голос
/ 09 апреля 2020

Простым C ++ 11-совместимым решением было бы делегировать подстановку аргумента вспомогательной функции, например make_shared для std::shared_ptr:

template<typename Fn, typename U, typename V>
K<Fn, U, V> make_K(Fn f, U u, V v) {
  return K<Fn, U, V>(f, u, v);
}

template<typename Fn, typename U>
K<Fn, U, U> make_K(Fn f, U u) {
  return K<Fn, U, U>(f, u);
}

, используемой как

auto k = make_K(koo, 3, 5.6);
auto m = make_K(moo, 3);
...