我最近遇到了很多命名参数习语很有用的情况,但我希望它在编译时得到保证。在链中返回引用的标准方法几乎总是调用运行时构造函数(使用 Clang 3.3 -O3 编译)。
我无法找到任何与此相关的内容,因此我尝试使用它constexpr
并获得一些功能:
class Foo
{
private:
int _a;
int _b;
public:
constexpr Foo()
: _a(0), _b(0)
{}
constexpr Foo(int a, int b)
: _a(a), _b(b)
{}
constexpr Foo(const Foo & other)
: _a(other._a), _b(other._b)
{}
constexpr Foo SetA(const int a) { return Foo(a, _b); }
constexpr Foo SetB(const int b) { return Foo(_a, b); }
};
...
Foo someInstance = Foo().SetB(5).SetA(2); //works
虽然这对于少量参数是可以的,但对于大量参数,它很快就会变成一团糟:
//Unlike Foo, Bar takes 4 parameters...
constexpr Bar SetA(const int a) { return Bar(a, _b, _c, _d); }
constexpr Bar SetB(const int b) { return Bar(_a, b, _c, _d); }
constexpr Bar SetC(const int c) { return Bar(_a, _b, c, _d); }
constexpr Bar SetD(const int d) { return Bar(_a, _b, _c, d); }
有没有更好的办法?我正在考虑使用具有许多(30 多个)参数的类来执行此操作,如果将来扩展,这似乎很容易出错。
编辑: 删除了 C++1y 标签——而 C++1y 似乎确实解决了问题(感谢 TemplateRex!)这是用于生产代码的,我们被 C++11 困住了。如果这意味着它不可能,那么我想这就是它的方式。
EDIT2:为了说明我为什么要寻找这个,这里有一个用例。目前使用我们的平台,开发人员需要为硬件配置显式设置位向量,虽然这没关系,但很容易出错。有些使用来自 C99 扩展的指定初始化程序,这没问题,但不标准:
HardwareConfiguration hardwareConfig = {
.portA = HardwareConfiguration::Default,
.portB = 0x55,
...
};
然而,大多数人甚至没有使用它,而只是输入了一大堆数字。因此,作为一项工作改进,我想朝着这样的方向发展(因为它也强制使用更好的代码):
HardwareConfiguration hardwareConfig = HardwareConfiguration()
.SetPortA( Port().SetPolarity(Polarity::ActiveHigh) )
.SetPortB( Port().SetPolarity(Polarity::ActiveLow) );
这可能更冗长,但稍后阅读时会更清晰。