mercredi 20 novembre 2019

C++11: Unable to infer template argument

the line:

    auto test = add<Suc < Suc < Suc < Suc < Zero > > > > > (three, one);

if I replace with:

    auto test = add(three, one);

I get error candidate template ignored: couldn't infer template argument 'W', using a Clang compiler with std=c++11 I can't imagine any other value satisfying W for it, is there a way to fix it?

#include <type_traits>

template<typename T>
class Nat {
};

class Zero : public Nat<Zero> {
};

template<typename T, 
    typename std::enable_if<std::is_base_of<Nat<T>, T>::value>::type* = nullptr>
class Suc : public Nat<Suc<T> > {
 public:
  T val;
  explicit Suc(T v): val(v) {}
};

template<typename T>
Suc<T> suc(T val) {
    Suc<T> next(val);
    return next; 
}

template<typename W, typename U, typename V,
    typename std::enable_if<std::is_base_of<Nat<W>, W>::value>::type* = nullptr,
    typename std::enable_if<std::is_base_of<Nat<U>, U>::value>::type* = nullptr,
    typename std::enable_if<std::is_base_of<Nat<V>, V>::value>::type* = nullptr
    >
W add(Suc<U> m, V n) {
    Suc<V> next (n);
    return add<W>(m.val, next);
}

template<typename V>
V add(Zero m, V n) {
    return n;
}

int main() {

    Zero zero;
    auto one = suc(zero);
    auto two = suc(one);
    auto three = suc(two);
    auto four = suc(three);

    auto test = add<Suc < Suc < Suc < Suc < Zero > > > > > (three, one);

    return 0;
}

Console output:

c++ -std=c++11 main.cc

main.cc:48:17: error: no matching function
      for call to 'add'
    auto test = add(three, one);
                ^~~
main.cc:35:3: note: candidate function
      template not viable: no known
      conversion from 'Suc<Suc<Suc<Zero,
      nullptr>, nullptr>, nullptr>' to
      'Zero' for 1st argument
V add(Zero m, V n) {
  ^
main.cc:29:3: note: candidate template
      ignored: couldn't infer template
      argument 'W'
W add(Suc<U> m, V n) {
  ^
1 error generated.

Aucun commentaire:

Enregistrer un commentaire