1

I am trying to write struct Fraction that does basic operations at compile time. Note that this does not serve any real purpose - I do this as an exercise only.

I started off with this:

namespace internal
{
    // Euclid algorithm
    template <int A, int B>
    struct gcd
    {
        static int const value = gcd<B, A % B>::value;
    };

    // Specialization to terminate recursion
    template <int A>
    struct gcd<A, 0>
    {
        static int const value = A;
    };
}

template <int Numerator, int Denominator>
struct Fraction
{
    // Numerator and denominator simplified
    static int const numerator = Numerator / internal::gcd<Numerator, Denominator>::value;
    static int const denominator = Denominator / internal::gcd<Numerator, Denominator>::value;

    // Add another fraction
    template <class Other> struct add
    {
        typedef Fraction<
            Numerator * Other::denominator + Other::numerator * Denominator,
            Denominator * Other::denominator
        > type;
    };
};

This compiles and works: Fraction<1,2>::add< Fraction<1,3> >::type will be Fraction<5,6>. Now I tried to add subtraction:

template <class Other>
struct sub
{
    typedef typename Fraction<Numerator, Denominator>::add<
        Fraction<-Other::numerator, Other::denominator>
    >::type type;
};

But I get a compiler error I do not understand:

Error: "typename Fraction<Numerator, Denominator>::add" uses "template<int Numerator, int Denominator> template <class Other> struct Fraction::add" which is not a type

Can someone explain to me what the compiler is saying, and why I am not allowed to do what I want? I am using g++ 4.4.6 by the way.

nijansen
  • 8,041
  • 8
  • 47
  • 68

1 Answers1

5

Use template keyword.

template <class Other>
struct sub
{
    typedef typename Fraction<Numerator, Denominator>::template add<
        Fraction<-Other::numerator, -Other::denominator>
    >::type type;
};

http://liveworkspace.org/code/26f6314be690d14d1fc2df4755ad99f6

Read this Where and why do I have to put the "template" and "typename" keywords? for better explanations.

Community
  • 1
  • 1
ForEveR
  • 52,568
  • 2
  • 101
  • 125