0

i got a Problem with a template I created a generic class whcih stores global available Information. This class holds a private mutex to manage the access to the global info.

template<typename Mutex_Type_T, typename Struct_Type_T>
class CGlobal_Struct
{
public:
/**
         * Exports data from this class to target
         * @param target the actual target
         * @param mutex_timeout Mutex wait time
         * @return true in case of success
         */
        bool Export(Struct_Type_T& target, const uint32_t mutex_timeout = 100);
        /**
         * Imports data to this class
         * @param source The data to store in this class
         * @param mutex_timeout Wait Time for Mutex
         * @return true in case of success
         */
        bool Import(const Struct_Type_T& source, const uint32_t mutex_timeout = 100);
             /**
     * 1) Loads Data to Buffer
             * 2) performs user defined Operation by calling func_T(data, args)
             * 3) stores back the data
     * @param User defined function
     * @param values class data to modify
             *  @param mutex_timeout Mutex wait time
     * @return true in case of success
     */
            template<typename func_T, typename func_arg_t>
        bool Replace(func_T(Struct_Type_T& values, const func_arg_t args), const func_arg_t func_args,const uint32_t mutex_timeout = 100);

private:
mutex _mutex;
}

This implementation Looks like this

template<typename Mutex_Type_T, typename Struct_Type_T>
template<typename func_T, typename func_arg_t>
bool CGlobal_Struct<Mutex_Type_T, Struct_Type_T>::Replace(func_T(Struct_Type_T& values, const func_arg_t args),const func_arg_t func_args, const uint32_t mutex_timeout)
    {
        CLock_Guard lock(mutex);

        //Lock access
        if(false == lock.Lock(mutex_timeout))
        {
                //Locking failed
            return false;
        }
        //Replace Data
        func_T(data, func_args);

        //Mutex is released automatically when we leave this function
        return true;
    }

Now first Question: is this template implementation correct?

Second: How would i call this replacement function from outside this class? Could you give me some help please?

JHeni
  • 21
  • 4
  • Possible duplicate of [Storing C++ template function definitions in a .CPP file](https://stackoverflow.com/questions/115703/storing-c-template-function-definitions-in-a-cpp-file) – Samer Tufail Mar 06 '19 at 14:49
  • `Now first Question: is this template implementation correct?` Does it compile? Did you tried calling it? – Guillaume Racicot Mar 06 '19 at 14:50
  • Your comment say "calling func_T(data, args)" but in your template, `func_T` is a typename, not a functor. – Raymond Chen Mar 06 '19 at 14:52

1 Answers1

0

Now first Question: is this template implementation correct?

Does it compile when you try calling it?

Second: How would i call this replacement function from outside this class?

The template arguments are deduced from a function pointer. Where func_T is the return type. I would advice against it and recommend a simpler template parameter:

template<typename Struct_Type_T>
struct CGlobal_Struct
{
    template<typename func_T, typename func_arg_t>
    bool Replace(func_T function, const func_arg_t func_args,const uint32_t mutex_timeout = 100) {
        // function(struct_type_value, func_args);
    }
};

Both version are valid and are called like this:

struct A {};

void func(A&, int) {}

int main() {
    CGlobal_Struct<A> glob;
    glob.Replace(func, 1);
}

The version I recommend can also support lambdas:

glob.Replace([](A&, int){ /* code */ }, 1);

Reading your implementation, it won't work with your current version:

//Replace Data
func_T(data, func_args);

The problem it that func_T is the type of the return type of the function sent as parameter. It is the same as this:

void(data, func_args);

Or more evil:

struct evil { evil(A&, int){} };

// ...

evil(data, func_args);

This will call the constructor of evil and never call a function.

It you look closely, your parameter has no name:

 bool Replace(
     func_T(Struct_Type_T&, const func_arg_t), 
 /* other params */ );

To give it a name, the sytax would be:

 bool Replace(
     func_T(*function)(Struct_Type_T&, const func_arg_t), 
 /* other params */ );

Then call function(...)

Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141