term does not evaluate to a function taking 1 arguments

K

KevinSimonson

I have been assigned to get the Shareaza source code running and then
to add some functionality to it. The open source is theoretically
what was used to generate a working Shareaza executable, but I'm
finding it kind of hard to believe that this code was actually
compiled. Take this section, for instance:

//! \brief generic function to swap the byte ordering of a given type
//!
//! The byte ordering can be swapped meaningfully only for unsigned
integer types
//! therefore specializations are provided only for those types. We
use
//! template specialization in order to avoid automatic argument
conversion.
template<typename T>
struct SwapEndianess {};

template<> struct SwapEndianess< uint8 >
{
uint8 operator()(uint8 value) const { return value; }
};
template<> struct SwapEndianess< uint16 >
{
uint16 operator()(uint16 value) const
{
return _byteswap_ushort( value );
}
};

template<> struct SwapEndianess< uint32 >
{
uint32 operator()(uint32 value) const
{
return _byteswap_ulong( value );
}
};

template<> struct SwapEndianess< uint64 >
{
uint64 operator()(uint64 value) const
{
return _byteswap_uint64( value );
}
};

template<typename T>
inline T swapEndianess(T value)
{
return SwapEndianess< T >()( value ); // <--- Error!
}

I added the little comment pointing at the error. Of this line the
compiler says,
"1>c:<pathname>\shareaza\hashlib\utility.hpp(221): error C2064: term
does not evaluate to a function taking 1 arguments". Now _it looks to
me_ like the solution to this syntax is just to take out the empty
pair of parentheses, change "return SwapEndianess< T >()( value );" to
"return SwapEndianess< T >( value );". Can anyone see any problem
with me doing that? If it doesn't compile, then I'll know right away,
but I thought I'd better let the readers of this forum know I'm doing
this in case they can see any logical errors that might result from me
doing this. Any pointers will be greatly appreciated.

Kevin S
 
L

Luc Danton

I have been assigned to get the Shareaza source code running and then
to add some functionality to it. The open source is theoretically
what was used to generate a working Shareaza executable, but I'm
finding it kind of hard to believe that this code was actually
compiled. Take this section, for instance:

//! \brief generic function to swap the byte ordering of a given type
//!
//! The byte ordering can be swapped meaningfully only for unsigned
integer types
//! therefore specializations are provided only for those types. We
use
//! template specialization in order to avoid automatic argument
conversion.
template<typename T>
struct SwapEndianess {};

template<> struct SwapEndianess< uint8>
{
uint8 operator()(uint8 value) const { return value; }
};
template<> struct SwapEndianess< uint16>
{
uint16 operator()(uint16 value) const
{
return _byteswap_ushort( value );
}
};

template<> struct SwapEndianess< uint32>
{
uint32 operator()(uint32 value) const
{
return _byteswap_ulong( value );
}
};

template<> struct SwapEndianess< uint64>
{
uint64 operator()(uint64 value) const
{
return _byteswap_uint64( value );
}
};

template<typename T>
inline T swapEndianess(T value)
{
return SwapEndianess< T>()( value ); //<--- Error!
}

I added the little comment pointing at the error. Of this line the
compiler says,
"1>c:<pathname>\shareaza\hashlib\utility.hpp(221): error C2064: term
does not evaluate to a function taking 1 arguments". Now _it looks to
me_ like the solution to this syntax is just to take out the empty
pair of parentheses, change "return SwapEndianess< T>()( value );" to
"return SwapEndianess< T>( value );". Can anyone see any problem
with me doing that? If it doesn't compile, then I'll know right away,
but I thought I'd better let the readers of this forum know I'm doing
this in case they can see any logical errors that might result from me
doing this. Any pointers will be greatly appreciated.

Kevin S

There is an extra set of parentheses because there is first a
constructor call. The next set of parentheses if a call to operator().
Now I am not familiar with this compiler error message but it is
possible that swapEndianess was instantiated with a type not supported
by SwapEndianess. Thus SwapEndianess<T>() indeed would not evaluate to a
"function" (which I assume has to be understood as "function-like
object") taking 1 argument because SwapEndianess only provides an
operator() in specializations.

Try removing the default template, i.e. only have:

template<typename T>
struct SwapEndianess;

which is a forward decl. and not a class/struct definition. If the error
message is something like 'use of an incomplete type' (you have to be
familiar with your compiler I'm afraid) then that's the error.
Alternatively you could put a static assertion in the default template
body but I'm not sure how this works (last time I tried my compiler
complained even when the template was not instantiated because the
static assertion did not depend on the template params).

Note that given some of your other threads posted for the same project,
I suspect that you have a misconfiguration somewhere: some types like
long or unsigned long seem to be different than what the original
writers expected (hence SwapEndianess<T> picked a specialization for
them, and they had implicit or no conversion at all to DWORD or whatever
other typedefs). Check that perhaps the project expects to be compiled
as 32bit if that maybe affects types on your toolchain.
 
K

KevinSimonson

There is an extra set of parentheses because there is first a
constructor call. The next set of parentheses if a call to operator().
Now I am not familiar with this compiler error message but it is
possible that swapEndianess was instantiated with a type not supported
by SwapEndianess. Thus SwapEndianess<T>() indeed would not evaluate to a
"function" (which I assume has to be understood as "function-like
object") taking 1 argument because SwapEndianess only provides an
operator() in specializations.

Try removing the default template, i.e. only have:

template<typename T>
struct SwapEndianess;

which is a forward decl. and not a class/struct definition. If the error
message is something like 'use of an incomplete type' (you have to be
familiar with your compiler I'm afraid) then that's the error.
Alternatively you could put a static assertion in the default template
body but I'm not sure how this works (last time I tried my compiler
complained even when the template was not instantiated because the
static assertion did not depend on the template params).

Note that given some of your other threads posted for the same project,
I suspect that you have a misconfiguration somewhere: some types like
long or unsigned long seem to be different than what the original
writers expected (hence SwapEndianess<T> picked a specialization for
them, and they had implicit or no conversion at all to DWORD or whatever
other typedefs). Check that perhaps the project expects to be compiled
as 32bit if that maybe affects types on your toolchain.

Okay, I removed the default template, so now it reads:

template<typename T>
struct SwapEndianess;

and I put back the empty parenthesis where I took it out, so down
below it reads:

template<typename T>
inline T swapEndianess(T value)
{
return SwapEndianess< T >()( value );
}

but then when I try to build it I still get an error message; this
time it says:
"1>c:\<path>\shareaza\hashlib\utility.hpp(221): error C2514:
'SwapEndianess<T>' : class has no constructors". So do I need to put
in a constructor? If so, I'm not sure how I'd write it. Would it be
enough to just write:

template<typename T>
struct SwapEndianess;

SwapEndianess ()
{
}

Or how should I write it?

Kevin S
 
L

Luc Danton

Okay, I removed the default template, so now it reads:

template<typename T>
struct SwapEndianess;

and I put back the empty parenthesis where I took it out, so down
below it reads:

template<typename T>
inline T swapEndianess(T value)
{
return SwapEndianess< T>()( value );
}

but then when I try to build it I still get an error message; this
time it says:
"1>c:\<path>\shareaza\hashlib\utility.hpp(221): error C2514:
'SwapEndianess<T>' : class has no constructors". So do I need to put
in a constructor? If so, I'm not sure how I'd write it. Would it be
enough to just write:

template<typename T>
struct SwapEndianess;

SwapEndianess ()
{
}

Or how should I write it?

Kevin S

No, I assume that this is the standard error message when trying to
instantiate an incomplete type. My original message offered help on how
to diagnose the error, not on how to fix it because it depends on what
you want to do. I made you change the empty default template into an
incomplete type so that we can now ascertain that we're trying
swapEndianess is called with a type T that SwapEndianess is not
specialized for. 'Fixing' this depends on what you want to do.

Namely, if you want to compile the code 'as is' to build the binaries
(i.e. you assume that there is no bug), I do not advise piling hack upon
hacks to coerce your compiler. *If* the original source once compiled
but doesn't now, I think you have configuration issues.
 
I

Ian Collins

I have been assigned to get the Shareaza source code running and then
to add some functionality to it. The open source is theoretically
what was used to generate a working Shareaza executable, but I'm
finding it kind of hard to believe that this code was actually
compiled. Take this section, for instance:

//! \brief generic function to swap the byte ordering of a given type
//!
//! The byte ordering can be swapped meaningfully only for unsigned
integer types
//! therefore specializations are provided only for those types. We
use
//! template specialization in order to avoid automatic argument
conversion.
template<typename T>
struct SwapEndianess {};

template<> struct SwapEndianess< uint8>
{
uint8 operator()(uint8 value) const { return value; }
};
template<> struct SwapEndianess< uint16>
{
uint16 operator()(uint16 value) const
{
return _byteswap_ushort( value );
}
};

template<> struct SwapEndianess< uint32>
{
uint32 operator()(uint32 value) const
{
return _byteswap_ulong( value );
}
};

template<> struct SwapEndianess< uint64>
{
uint64 operator()(uint64 value) const
{
return _byteswap_uint64( value );
}
};

template<typename T>
inline T swapEndianess(T value)
{
return SwapEndianess< T>()( value ); //<--- Error!
}

I added the little comment pointing at the error. Of this line the
compiler says,
"1>c:<pathname>\shareaza\hashlib\utility.hpp(221): error C2064: term
does not evaluate to a function taking 1 arguments".

There nothing wrong with the code, the compiler is probably trying to
tell you you are calling swapEndianess() with something other than an
unsigned type (no specialisation found).
 
J

Jorgen Grahn

On 10/23/10 01:50 PM, KevinSimonson wrote: ....
struct SwapEndianess {};
....
There nothing wrong with the code, the compiler is probably trying to
tell you [...]

Well, there are at least two problems:
- unconditional swapping is a hint that there may be a design flaw
in the code, or in the network protocol. I wouldn't be surprised if
they're also doing non-portable casts (like taking an uint8_t* and casting
it to uint32_t*).
- they spell 'endianness' incorrectly :)

/Jorgen
 
B

Bo Persson

Ian said:
There nothing wrong with the code, the compiler is probably trying
to tell you you are calling swapEndianess() with something other
than an unsigned type (no specialisation found).

Well, there are some things wrong with the code, like using the names
swapEndianess and SwapEndianess (two wrongs actually). Also,
specializing templates, or overloading functions, on typedefs are just
asking for trouble.

To me it is obvious that the original coder expects uint32 to match
all 32 bit unsigned types for the platform. It does not!


Bo Persson
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,152
Members
46,697
Latest member
AugustNabo

Latest Threads

Top