C ++可变参数模板 - 限制args数

时间:2015-10-03 09:53:27

标签: c++ templates c++11 variadic-templates

我有一个带有set函数的可变参数模板类,它填充了内部数组:

int splitString()
{
    char source[] = "str1,str2,str3,str4";
    char *token = NULL;
    char **rowIndexes = NULL;
    int size = 0, index = 0;

    rowIndexes = malloc(sizeof(char));//allocate memory for dynamic array
    if (rowIndexes == NULL)
    {
        printf("memory allocation failed");
    }

    token = strtok(source, ",");
    while (token)//split string into tokens to ","
    {
        rowIndexes = realloc(rowIndexes, sizeof(char*)*(++size));//realloate memory if needed
        if (rowIndexes == NULL)
        {
            printf("memory allocation failed");
            return -1;
        }

        rowIndexes[size - 1] = token;
        token = strtok(NULL, ",");
    }

    for (index = 0; index < size; index++)
    {
        free(rowIndexes[index]);
    }
    free(rowIndexes);

    return 0;
}

问题是,我可以称之为

template <size_t Dim>
class Vector
{
public:

    void SetValueTemplate(size_t index)
    {
        return;
    }

    template <typename X0, typename ...Xn>
    void SetValueTemplate(size_t index, X0 x0, Xn... xn)
    {
        val[index] = x0;
        SetCenterValueTemplate(index + 1, xn...);
    }

    template <typename ...X0>
    void SetValue(X0... t0)
    {
        SetValueTemplate(0, t0...);
    }

private:
    double val[Dim];
};

它正确编译。我可以将此限制为不编译吗?我可以使用Vector<3> v; v.SetValue(0, 1, 2, 4, 5); ,但没有它可能吗?

1 个答案:

答案 0 :(得分:4)

是的,没有static_assert这是可能的。例如,假设我们希望我们的vector类只能使用参数的名称编号作为向量的维度进行赋值,您可以使用:

template<std::size_t Dim>
struct vector {
    template <typename X0, typename ...Xn>
    typename std::enable_if<sizeof...(Xn) + 1 == Dim, void>::type
    assign(X0 x0, Xn... xn) {}
};

这只是将std::enable_ifsizeof...结合使用来启用或禁用特定的分配功能。

以下将编译:

vector<3> x;
x.assign(1, 2, 3);

Live demo

但这不会:

vector<3> x;
x.assign(1, 2, 3, 4);

Live demo

with(for Clang):

main.cpp:14:7: error: no matching member function for call to 'assign'
    x.assign(1, 2, 3, 4);
    ~~^~~~~~

,这也不会:

vector<3> x;
x.assign(1, 2);

Live demo

有类似的错误消息。