Проблема с параметрами varadic шаблона - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь написать вспомогательный шаблонный метод, который принимает имена типов для каждого вида анализа, который я хочу сделать. Я хочу, чтобы API выглядел примерно так:

doMultiAnalysis<FrequencyResult, DiffusionResult, GeneralCipherResult>(vector, plainText, cipherText, length, a1Context, (TroyCipher*) &a1, 1000);

Я создал этот рекурсивный шаблон, который работает с текущим аргументом шаблона, а затем передает остальное обратно в функцию:

template<typename T, typename... rest>
void doMultiAnalysis(std::vector<Result*>& vector, u8* plainText, u8* cipherText, u64 length, TroyContext* context, TroyCipher* cipher, u32 iterations) {
    T* result = new T{};
    result->doAnalysis(plainText, cipherText, length, context, cipher, iterations);
    vector.push_back((Result*) result);
    std::cout << *result << std::endl;
    doMultiAnalysis<rest...>(vector, plainText, cipherText, length, context, cipher, iterations);
}

Если я пытаюсь скомпилировать этот код с MSVC, я, конечно, получаю «Не найдено подходящих перегруженных функций», потому что базовый вариант не существует. Так что, если я сделаю это:

template<typename T, typename... rest>
void doMultiAnalysis(std::vector<Result*>& vector, u8* plainText, u8* cipherText, u64 length, TroyContext* context, TroyCipher* cipher, u32 iterations) {
    T* result = new T{};
    result->doAnalysis(plainText, cipherText, length, context, cipher, iterations);
    vector.push_back((Result*) result);
    std::cout << *result << std::endl;
    doMultiAnalysis<rest...>(vector, plainText, cipherText, length, context, cipher, iterations);
}

template<typename none = void>
constexpr void doMultiAnalysis(std::vector<Result*>& vector, u8* plainText, u8* cipherText, u64 length, TroyContext* context, TroyCipher* cipher, u32 iterations) {
}

Компилятор выдает «неоднозначный вызов перегруженной функции» в строке:

doMultiAnalysis<rest...>(vector, plainText, cipherText, length, context, cipher, iterations);

Что я здесь не так делаю?

Также я знаю, что самодельная криптография - плохая идея. Это личный проект для развлечения, который никогда не будет использован в производстве.

1 Ответ

0 голосов
/ 14 января 2019

Предложение: попробуйте с

template <int = 0>
constexpr void doMultiAnalysis(std::vector<Result*>& vector, u8* plainText, u8* cipherText, u64 length, TroyContext* context, TroyCipher* cipher, u32 iterations) {
}

вместо

template<typename none = void>
constexpr void doMultiAnalysis(std::vector<Result*>& vector, u8* plainText, u8* cipherText, u64 length, TroyContext* context, TroyCipher* cipher, u32 iterations) {
}

С вашей версией, вызывающей doMultiAnalysis() с последним типом, у вас возникает неоднозначность, потому что оба doMultianalysis() совпадают.

С

template <int = 0>
constexpr void doMultiAnalysis(...)

у вас есть вызов doMultiAnalysis() с последним типом, совпадающий только с версией переменной, а когда эта версия вызывает doMultiAnalysis<rest...>() с пустым списком rest..., совпадает (только) с версией int = 0.

...