可变模板参数问题

时间:2019-01-14 19:18:45

标签: c++ c++11 visual-c++ variadic-templates template-meta-programming

我正在尝试编写一个帮助程序模板方法,该方法接受要进行的每种分析的类型名称。我希望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 :(得分:2)

建议:尝试

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版本。