Afshin
Afshin

Reputation: 9173

deducing template specilization based on constructor arguments

I'm trying to provide a small class specialization when 2 provided types are similar and I have reached following code that works:

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);
}

My only problem is that to select the specialization, I must provide <decltype(moo), int, int> manually or the specialization will not picked. I wonder if it is possible to pick this specialization based on single constructor argument so K(moo,3); works too. Any idea?

Upvotes: 0

Views: 37

Answers (2)

Jarod42
Jarod42

Reputation: 218098

In C++17, provide deduction guide for CTAD:

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

Demo

Upvotes: 2

Xatyrian
Xatyrian

Reputation: 1384

A simple C++11-compatible solution would be to delegate the argument substitution to a helper function like make_shared for the 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);
}

used as

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

Upvotes: 1

Related Questions