可变参数模板参数问题

Issue with varadic template parameters

我正在尝试编写一个辅助模板方法,为我想做的每种分析获取类型名称。我希望 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 编译此代码,我当然会得到 "No matching overloaded functions found",因为基本情况不存在。所以如果我这样做:

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

编译器给出"ambiguous call to overloaded function"行:

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

我做错了什么?

我也知道自制加密是个坏主意。这是一个个人娱乐项目,绝不会用于生产。

建议:试试

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() 只匹配可变版本,当这个版本用空 rest... 列表调用 doMultiAnalysis<rest...>() 时,(只)匹配 int = 0版本。