将具有可选模板类型参数的函数传递给类构造函数并将其分配给方法

Dam*_*ola 6 c++

我有两个文件:main.cppcrypto.h包含模板类Crypto.在类构造函数中,我需要传递一个函数指针并将其分配给(*keyGen)方法.我需要传递的函数有一个可选的参数

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
        }
};
Run Code Online (Sandbox Code Playgroud)

在main.cpp中

int keyGen(int key = -1) { // This is the optional param
    key++;
    return key;
}

int main() {
    // ...
    Crypto<int> crypto(keyGen);
    crypto.decode();
}
Run Code Online (Sandbox Code Playgroud)

我需要解码方法能够使用无参数或keyType参数调用keyGen.如果没有参数调用keyGen我需要返回0,否则我需要返回键+ 1.我想过重载keyGen函数,但因为它是一个函数指针,所以不可能.我做了很多研究,但我找不到解决方案.

Mat*_*jek 3

如果你想同时拥有keyGen()keyGen(curKey)keyGen它本身必须是一个带有默认参数的函数。请注意,签名中的默认值不会更改该签名 - 因此指向的指针int keyGen(int key = -1)必须是类型int(*)(int)

您可以添加两个同名的成员函数,它们在内部调用带有keyGen正确参数的指向的函数:

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);
    }

};
Run Code Online (Sandbox Code Playgroud)

但要成为一个正确的解决方案,您需要知道密钥的默认值 - 您不能简单地将其放在那里-1,因为对于不同的密钥类型,该值也可能不同。但您可以将此值作为附加模板参数:

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();
}
Run Code Online (Sandbox Code Playgroud)

或将其传递给构造函数并存储为成员:

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();
}
Run Code Online (Sandbox Code Playgroud)

我认为这是最直接的解决方案。