如何防止大括号初始化器在函数重载中被解释为整数?

How to prevent brace-initializer being interpreted as integer in function overload?

我有一个存储代数项的 Expression class。我希望它具有的 public 界面类似于:

expr.add({1})      // add term "x1".         (error: code adds constant 1)
expr.add({0,1})    // add term "x0 * x1".
expr.add({0},2)    // add term "2 * x0"
expr.add(2)        // add constant 2

但我遇到的问题是 expr.add({1}) 被解释为添加整数 1,而不是添加包含 1 的向量。有什么方法可以修复下面的实现以允许上面的接口? (或者至少抓住它?)因为输入 expr.add(std::vector({1})) 太冗长了。

#include <tuple>
#include <vector>
#include <unordered_set>
#include <iostream>

class Expression
{
    using var_t = unsigned int;
    using term_t = std::pair<int, std::vector<var_t>>;

    std::vector<term_t> terms;

  public:

    void add(const std::vector<var_t>& vars, int coeff=1)
    {
        std::cout << "Adding a term" << std::endl;
        terms.push_back(std::make_pair(coeff, vars));
    }
    void add(int constant)
    {
        std::cout << "Adding a constant" << std::endl;
        terms.push_back(std::make_pair(constant, std::vector<var_t>{}));
    }
};

int main()
{
    Expression expr;
    expr.add({1},1); // "Adding a term"
    expr.add({1});   // "Adding a constant"
    expr.add(1);     // "Adding a constant"
}

您可以将参数类型更改为std::initializer_list,这将是首选。

void add(std::initializer_list<var_t> vars, int coeff=1)
{
    std::cout << "Adding a term" << std::endl;
    terms.push_back(std::make_pair(coeff, std::vector<var_t>(vars)));
}

LIVE

您可以为 initializer_list 添加重载,如果它在大括号初始值设定项中,它将绑定到参数

void add(std::initializer_list<var_t> vars, int coeff=1)
{
    add(std::vector<var_t>(vars), coeff);
}

在实现中,您可以显式调用 vector 重载 and/or 给用户一个警告。

这是一个demo

您可以在参数中将其更改为initializer_list

void add(std::initializer_list<var_t> vars, int coeff=1)