I have two files: main.cpp
and crypto.h
containing the template class Crypto. In the class constructor I need to pass a function pointer and assign it to the (*keyGen) method. The function I need to pass has an optional param
template <class keyType>
class Crypto {
private:
keyType (*keyGen)(keyType);
public:
Crypto(keyType (*keyGen)(keyType)) {
this->keyGen = keyGen;
}
void decode() {
keyType foundKey;
vector<string> output;
keyType curKey = keyGen(); // Here keyGen has no args
// if curKey does not decode the input
curKey = keyGen(curKey); // Here keyGen has 1 arg of type keyType
// else foundKey = curKey;
// Save the decoded file
}
};
In main.cpp
int keyGen(int key = -1) { // This is the optional param
key++;
return key;
}
int main() {
// ...
Crypto<int> crypto(keyGen);
crypto.decode();
}
I need the decode method to be able to call keyGen with both no params or a keyType param. If keyGen is called with no params I need to return 0, else I need to return key+1. I thought about overloading the keyGen function, but since it is a function pointer it is not possible. I did a lot of research but I didn't find a solution.
Defining a Function TemplateA function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.
A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.
A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument. A non-type parameter can be any of the following types: An integral type. An enumeration type. A pointer or reference to a class object.
To instantiate a template class explicitly, follow the template keyword by a declaration (not definition) for the class, with the class identifier followed by the template arguments. template class Array<char>; template class String<19>; When you explicitly instantiate a class, all of its members are also instantiated.
If you want to have both keyGen()
and keyGen(curKey)
available, keyGen
must be itself a function with default param. Note, that default value in signature does not change that signature - so pointer to int keyGen(int key = -1)
must be of type int(*)(int)
.
You could add two member function of the same name, that internally call the function pointed to by keyGen
with proper args:
template <class keyType>
class Crypto {
...
void decode() {
keyType foundKey;
vector<string> output;
keyType curKey = keyGenInternal(); // Here keyGen has no args
// if curKey does not decode the input
curKey = keyGenInternal(curKey); // Here keyGen has 1 arg of type keyType
// else foundKey = curKey;
// Save the decoded file
}
private:
keyType keyGenInternal() {
return keyGen(-1);
}
keyType keyGenInternal(keyType key) {
return keyGen(key);
}
};
But for this to be a proper solution, you need to know the default value for the key - you can't simply put there -1
, because for different key types this value may also be different. But you can make this value an additional template parameter:
template <class keyType, keyType defaultKey>
class Crypto {
private:
keyType keyGenInternal() {
return keyGen(defaultKey);
}
keyType keyGenInternal(keyType key) {
return keyGen(key);
}
};
int main() {
// ...
Crypto<int, -1> crypto(keyGen);
crypto.decode();
}
or pass it to constructor and store as a member:
template <class keyType>
class Crypto {
private:
keyType defaultKey;
public:
Crypto(keyType (*keyGen)(keyType), keyType default) : defaultKey(default) {
this->keyGen = keyGen;
}
};
int main() {
// ...
Crypto<int> crypto(keyGen, -1);
crypto.decode();
}
I think it is the most straightforward solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With