Template compilation error w GCC 7.1.0 (ambiguous overload)

support for the ARM toolchain
Post Reply
bim
Posts: 7
Joined: Fri Nov 03, 2017 6:56 pm

Template compilation error w GCC 7.1.0 (ambiguous overload)

Post by bim » Fri Nov 03, 2017 9:23 pm

I picked up an old GBA project I would like to finish now. I have a template fixed-point class (ideone example) with tests that compiles with GCC 5.4 (my PC) and 6.3 (IdeOne) and even 7.1 (wandbox), but not the 7.1 included in the current devkitArm. I've tried a couple of things now, but can not get it to work.
GCC always tells me that:

Code: Select all

/src/test.cpp: In function 'int main()':
/src/test.cpp:7:13: error: call of overloaded 'fp(int)' is ambiguous
  fp1616 a0(0);
             ^
In file included from /src/test.cpp:1:0:
/src/test.h:10:2: note: candidate: fp<F>::fp(const float&) [with int F = 16]
  fp(const float & b) : s(b * (1 << F)) { }
  ^~
/src/test.h:9:2: note: candidate: fp<F>::fp(const int32_t&) [with int F = 16; int32_t = long int]
  fp(const int32_t & b) : s(b << F) { }
  ^~
/src/test.h:4:8: note: candidate: constexpr fp<16>::fp(const fp<16>&)
 struct fp
        ^~
Before I go insane: Does anybody have an idea?

WinterMute
Site Admin
Posts: 1986
Joined: Tue Aug 09, 2005 3:21 am
Location: UK
Contact:

Re: Template compilation error w GCC 7.1.0 (ambiguous overlo

Post by WinterMute » Sun Nov 05, 2017 4:12 pm

Newlib based toolchains define int32_t as long, literal numbers with no suffix are int. Easiest solution is so use int in your templates instead of int32_t
Help keep devkitPro toolchains free, Donate today

Personal Blog

mtheall
Posts: 211
Joined: Thu Feb 03, 2011 10:47 pm

Re: Template compilation error w GCC 7.1.0 (ambiguous overlo

Post by mtheall » Sun Nov 05, 2017 11:20 pm

I made some changes and this seems to work:

Code: Select all

#include <cstdint>
#include <iostream>

template <unsigned F> // changed F to unsigned
struct fp
{
  static_assert(F < 32); // assert shifts are valid

  constexpr static unsigned BITS = F; // change to constexpr static member instead of enum

  int32_t s; // to make sure it's exactly 32-bits wide on any platform

  // this gives the same result for both integral and floating-point types,
  // and the optimizer makes it as efficient as you had before with them separate
  template <typename T>
  fp(const T & b) : s(b * (1 << F)) { }

  // this was fine; delegates to operator=
  // this will be chosen over the previous template because it is more specific
  template<unsigned T>
  fp(const fp<T> & b) { *this = b; }

  // same reason as constructor; no need to have separate integral and floating-point
  // implementations
  template <typename T>
  fp & operator=(const T & b) { s = b * (1 << F); return *this; }

  // removed operator=(const fp &) since it's already covered by this
  template<unsigned T>
  fp & operator=(const fp<T> & b)
  {
    if (T > F) { s = b.s >> (T - F); }
    else if (T < F) { s = b.s << (F - T); }
    else { s = b.s; }
    return *this;
  }

  // removed template argument because it's already implied
  friend std::ostream & operator<<(std::ostream & os, const fp & a) { os << a.s; return os; }
};

using fp824 = fp<24>;
using fp1616 = fp<16>;
using fp248 = fp<8>;

int main() {
  // your code goes here
  fp1616 a0(0);
  fp1616 a1(1);
  fp1616 a2(2);
  fp1616 a3(-2.5f);
  std::cout << a0 << std::endl;
  std::cout << a1 << std::endl;
  std::cout << a2 << std::endl;
  std::cout << a3 << std::endl;
  a0 = 5;
  a0 = 0;
  a0 = 3.4f;
  fp824 b1(1.2f);
  fp1616 b2(b1);
  fp248 b3(b2);
  b1 = b3;
  b1 = b2;
  return 0;
}

bim
Posts: 7
Joined: Fri Nov 03, 2017 6:56 pm

Re: Template compilation error w GCC 7.1.0 (ambiguous overlo

Post by bim » Wed Nov 08, 2017 9:46 am

Not sure if my previous answer got lost, so:
Thanks for the answers. It was indeed the int vs. int32_t problem. My solution looks something like this atm. I wasn't sure about the compilers capabilities, so the different overloads...

Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests