0
votes

EDITED (Original Question had only int A, int B):
Template argument deduction works as expected when the #arguments compared between specializations is the same, but fails when they are different (due to including default parameters included in one of the specialization).

For example : Why does template argument deduction fail in one case vs the other, can someone point to any resources / standard where this is explained ?

// Example program
#include <iostream>

template <int A, int B, int C, int D=1>
class Foo;

template <int A, int B, int C>
class Foo <A, B, C>
{
public:
    int a;

    Foo()
    {
        a = 0;
    }
};

template <int D>               // Fails compilation
class Foo <1, 1, 1, D>         // Fails compilation
//template <>                  // works, prints a = 1
//class Foo <1, 1, 1>          // works, prints a = 1
{
public:
    int a;

    Foo()
    {
        a = 1;
    }
};


int main()
{
    Foo <1, 1, 1, 1> f;
    std::cout << "a = "<< f.a << std::endl;
}

error: ambiguous template instantiation for ‘class Foo<1, 1, 1, 1>’

1

1 Answers

1
votes
template <int A>
class Foo <A> {/*..*/};

is with default argument:

template <int A>
class Foo <A, 1> {/*..*/};

With (valid):

template <int B>
class Foo <1, B> { /*..*/ };

You have ambiguity for Foo<1, 1>, both Foo<A, 1> and Foo<1, B> match, but neither is more specialized.

template <> class Foo <1> { /**/};

is

template <> class Foo <1, 1> { /**/};

and is more specialized than both previous specializations.