Templated function error: no matching function for call to

Hiya all

I posted to fast ... I figured it out, Sorry!

Still learning and have not got to templates yet and am lost ...

Trying to compile the latest [url=https://github.com/taglib/taglib]Taglib[/url] master branch on FreeBSD-8.2 and get the following errors, I've asked there and get no response or resolution, so here I am.
I've included the errors and relevant code commented with line numbers.

Hopefully someone can point me in the right direction.

The Errors:
taglib/taglib/toolkit/tbytevector.cpp: In function 'T TagLib::toNumber(const TagLib::ByteVector&, size_t, bool) [with T = unsigned int]':
taglib/taglib/toolkit/tbytevector.cpp:804: instantiated from here
taglib/taglib/toolkit/tbytevector.cpp:303: error: no matching function for call to 'toNumber(const TagLib::ByteVector&, size_t&, unsigned int, bool&)'
taglib/taglib/toolkit/tbytevector.cpp: In function 'T TagLib::toNumber(const TagLib::ByteVector&, size_t, bool) [with T = short unsigned int]':
taglib/taglib/toolkit/tbytevector.cpp:819: instantiated from here
taglib/taglib/toolkit/tbytevector.cpp:303: error: no matching function for call to 'toNumber(const TagLib::ByteVector&, size_t&, unsigned int, bool&)'
taglib/taglib/toolkit/tbytevector.cpp: In function 'T TagLib::toNumber(const TagLib::ByteVector&, size_t, bool) [with T = long long unsigned int]':
taglib/taglib/toolkit/tbytevector.cpp:839: instantiated from here
taglib/taglib/toolkit/tbytevector.cpp:303: error: no matching function for call to 'toNumber(const TagLib::ByteVector&, size_t&, unsigned int, bool&)'


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// Line# 298
template <class T>
T toNumber(const ByteVector &v, size_t offset, bool mostSignificantByteFirst)
{
  if(offset + sizeof(T) > v.size()) 
    return toNumber<T>(v, offset, v.size() - offset, mostSignificantByteFirst);  // Line# 303

  // Uses memcpy instead of reinterpret_cast to avoid an alignment exception.
  T tmp;
  ::memcpy(&tmp, v.data() + offset, sizeof(T));

#if SYSTEM_BYTEORDER == 1
  const bool swap = mostSignificantByteFirst;
#else
  const bool swap != mostSignificantByteFirst;
#endif
  if(swap)
    return byteSwap<T>(tmp);
  else
    return tmp;
}

template <class T>
T toNumber(const ByteVector &v, size_t offset, size_t length, bool mostSignificantByteFirst)
{
  if(offset >= v.size()) {
    debug("toNumber<T>() -- No data to convert. Returning 0.");
    return 0;
  }

  length = std::min(length, v.size() - offset);

  T sum = 0;
  for(size_t i = 0; i < length; i++) {
    const size_t shift = (mostSignificantByteFirst ? length - 1 - i : i) * 8;
    sum |= static_cast<T>(static_cast<uchar>(v[offset + i])) << shift;
  }

  return sum;
}

// line# 801
TagLib::uint ByteVector::toUInt(bool mostSignificantByteFirst) const
{
  return toNumber<uint>(*this, 0, mostSignificantByteFirst); // Line# 804
}

// Line# 816
short ByteVector::toShort(bool mostSignificantByteFirst) const
{
  return toNumber<unsigned short>(*this, 0, mostSignificantByteFirst);  // Line# 819
}

// Line# 836
long long ByteVector::toLongLong(bool mostSignificantByteFirst) const
{
  return toNumber<unsigned long long>(*this, 0, mostSignificantByteFirst);  // Line# 839
}


Thank you
Joe
Last edited on
Which version of GCC are you using?
This looks like a bug in earlier versions of GCC. I have tried compiling this using ideone. It compiles fine for GCC 4.7.2, but has errors you've shown if I use GCC 4.3.2.

The thing is that name lookup for templates is split in two phases. First, the compiler looks up the names that do not depend on the template parameters at the point of template definition. The dependent names are looked up later, at the point of instantiation. So basically, the toNumber function with 4 parameters should be looked up when the template toNumber with 3 parameters is instantiated, i.e. lines 804, 819, and 839. At that point, the 4-parameter version is already declared. However, at line 303 it is not yet declared. This shouldn't come as a problem when the two-phase lookup is implemented correctly - but it happens in your case so I assume that it is a compiler bug.

Moving the toNumber with 4 parameters or just forward-declaring it before toNumber with 3 parameters should fix your problem.
Last edited on
1
2
3
4
5
6
# g++ -v
Using built-in specs.
Target: i386-undermydesk-freebsd
Configured with: FreeBSD/i386 system compiler
Thread model: posix
gcc version 4.2.1 20070719  [FreeBSD]


Lack of prototype or function order however one wants to look at it ...

Flipped the two template functions and on it went!

Thanks, I've been looking at this for two days, the fact that it's a template and the way the error is is written out had me pulling my hair.
Last edited on
Topic archived. No new replies allowed.