# Can't compile a function using a "call_trait" for parameter type and return type

This topic is 3460 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

The call_traits class:
#ifndef _CALL_TRAITS_HPP_
#define _CALL_TRAITS_HPP_

template<class T, bool TOO_BIG>
struct decide
{
typedef T const& parameter;
};

template<class T>
struct decide<T, false>
{
typedef T parameter;
};

template<class T>
class call_traits
{
static const bool TOO_BIG = sizeof( T ) > 8;//( 2 * sizeof( void * ) );

public:
typedef typename decide<T, TOO_BIG>::parameter param_type;
};

#endif


the Euler class( I've removed all the interesting code ):
#ifndef _EULER_HPP_
#define _EULER_HPP_

#include "call_traits.hpp"

//template<class T> class call_traits;

class Euler
{
public:

Euler(){}
//~Euler(){}

template<typename Real>
Real returnParameter( typename call_traits<Real>::param_type param )const
{
return param;
}
};


and finally, the main.cpp file
#include <iostream>
#include "Euler.hpp"
using namespace std;

int main()
{
cout << "euler.returnParameter( 1.0 ) = " << euler.returnParameter( 1.0 ) << endl;

return 0;
}


Here's what the error message generated by the compiler( GCC ): H:\profile\Bureau\PE\main.cpp In function int main()': H:\profile\Bureau\PE\main.cpp no matching function for call to Euler::returnParameter(double)' H:\profile\Bureau\PE\Makefile.win [Build Error] [main.o] Error 1 It seems as if I had
template<>
call_traits<double>
{
static const bool TOO_BIG = false;

public:
typedef double& param_type;
};


which doesn't make sense. Maybe am I too tired? Could someone explain me what's going on?

##### Share on other sites
Where is the object named euler defined?

##### Share on other sites
Assuming euler is declared somewhere, it seems that it is unable to detect the type for Real so as to instantiate the call_trait object. It would work if you told it:

euler.returnParameter<double>( 1.0 )

Someone more knowledgeable in metaprogramming might explain why it is so.

Incidentally, I don't think you need the static bool:

typedef typename decide<T, (sizeof(T) > 8)>::parameter param_type;

(I'm not that sure that the sizeof something alone tells you how it is optimal to pass it. For example, sizeof(std::string) might be 4 for some implementations, so you would prefer to pass a string by value?)

##### Share on other sites
Quote:
 Original post by visitorAssuming euler is declared somewhere, it seems that it is unable to detect the type for Real so as to instantiate the call_trait object. It would work if you told it:euler.returnParameter( 1.0 ) Someone more knowledgeable in metaprogramming might explain why it is so.Incidentally, I don't think you need the static bool:typedef typename decide 8)>::parameter param_type;(I'm not that sure that the sizeof something alone tells you how it is optimal to pass it. For example, sizeof(std::string) might be 4 for some implementations, so you would prefer to pass a string by value?)

The object was properly declared: I just removed the non-related code( in the main.cpp and Euler.hpp files ) and accidently removed the declaration of euler. I simply think that the compiler cannot deduce the type of the parameter and hence the return type: I initially thought that "1.0" would be interpreted as a double constant, but even using a double variable didn't solve the problem. Maybe because the parameter is declared to be of the type "call_traits<Real>::param_type" and not simply of the type "Real"...
I'm going to look in a C++ book dedicated to template programming( C++ Template Programming: The complete Guide? ) to see if there's a mean to declare a function whose signature can get parametrizable, the way I want it to be.

Thanks for your help: I will have to replace a lot of tokens in my code!!! :D
I should have tested a very short function(like the one I posted) before even modifying my whole code...
For the size stuff( size's stuff? ), the optimization has only to do with the time taken to read and access an adress of 8 bytes. It's independent of specfic implementations, but just related to the "size"( bytes used to represente it ) of a physical adress and the time to access it and copy the value stored.
That's what I understood. I do not want to pass a string value, because, it is not the purpose of the optimization: but if I can gain time by passing a reference to a constant long double, then it is worth optimizing. Yes, you are going to tell me I should first profile the code...

[Edited by - johnstanp on August 2, 2008 7:29:08 PM]