是否可以将一组值传递给可变参数模板声明,类似于斐波那契数列的求解方式

Is it possible to pass a set of values to a variadic template declaration similar to how the fibonacci series is solved

我正在寻找一个带有模板的解决方案,它允许我将值作为模板参数传递,就像通过使用特定数据类型专门化模板所做的那样。例如

template <std::string... Args>
struct MOptional
{
    MOptional()
    {
        possibilities.push_back(std::forward(Args)...);
    }

    std::vector<std::string> possibilities;
};

我想要的使用方式是这样的。

MOptional<"string1", "string2", "string3"> optional;

因此 class 中的可能性字段应该自动填充字符串 1、字符串 2 和字符串 3。我知道我可以用构造函数来做,但我正在寻找类似上面的东西。我希望字符串的数量是可变的。

显然这段代码无法编译,只是为了传达我想要的...

有什么想法吗?

最终解决方案(由 Barry 编辑)

template <typename T, T... Args>
struct MOptional
{
    MOptional()
    {
        // enum { N = sizeof...(Args) };
        T arr[] = { Args... };
        possibilities.assign(std::begin(arr), std::end(arr));
    }

    std::vector<T> possibilities;
};

你不能有 string 模板参数,但是你可以用你 可以 作为模板非类型参数的任何类型做你想做的事:

template <typename T, T... Args>
struct MOptional
{
    MOptional()
    : possibilities{Args...}
    { }

    std::vector<T> possibilities;
};

例如,ints:

MOptional<int, 1, 2, 3> mo;
std::cout << mo.possibilities.size(); // prints 3

由于 MSVC 在可变参数模板支持方面有点落后,因此可以改为执行以下操作:

MOptional() {
    T arr[] = {Args...};
    possibilities.assign(std::begin(arr), std::end(arr));
}

无法使用字符串或其他对象作为模板参数。不过,我成功完成的是使用 c 字符串的 constexpr 散列。这是它的样子:

/**
* @brief Hashes a given c-string using the FNV-1a standard hash.
* @details This is used eg. to use strings as template arguments.
*/
constexpr uint64_t template_hash(const char* x) {
    return *x ? (uint64_t(*x) ^ template_hash(x+1))*1099511628211ul : 14695981039346656037ul;
}

template<uint64_t hash> struct foo { static uint64_t bar() { return hash;} };

int main() {
    std::cout << foo<template_hash("test")>::bar() << std::endl;
}

应该可以正常工作。显然这不允许您检索字符串,但您可以根据字符串区分 类 。通过修改散列,您可以在模板参数中编码一个 8-10 个字母的字符串,但对于更多,您将不得不做一些工作...... 如果您确实需要 8 个字符的版本:

constexpr uint64_t template_string(const char* x) {
    return *x ? (uint64_t(*x) | (template_string(x+1)<<8)) : 0ul;
}

我会把它留给你来解码那个字符串。