这目前是伪代码,因为在开始将其作为完整代码编写之前,我正在努力处理这一想法。
[我知道我可以创建一个使用va_arg
和va_list
的普通可变参数函数,例如printf()
,但是我想避免完全使用它们。
我当时正在考虑使用模板化的可变参数。我当时正在考虑制作一个使用可变参数作为模板的可实例化类。这里的条件是该类的构造函数只能接受两种类型,但是每种类型的数量都可以变化。我知道与在编译器中解释参数的方式和调用顺序相比,在代码中写入参数的位置是不可知的,但这不是问题。根据惯例,出于可读性和一致性的目的,我为参数选择的顺序是。
这是伪代码的示例:
class TypeIn {...}
class TypeOut{...}
template<typename... T1, typename... T2>
class MyObject {
std::array<TypeIn*> inputs_;
std::array<TypeOut*> outputs_;
public:
MyObject(T1&&... inputs, T2&& ... outputs) { ... }
};
由于我仍在使用C ++ 17,并且还没有包含概念,模块和协程的C ++ 20,因此,确保T1
是最干净,最可靠,最有效的方法是什么? TypeIn
和T2
是TypeOut
类对象,并据此填充数组?我可以使用矢量,但是一旦构建了对象,输入和输出的大小就不会改变。
可能的用例是:
using In = TypeIn;
using Out = TypeOut;
MyObject obj( In a, In b, In c, Out x, Out y);
而且我也不希望在语法上不要使用它:
MyObject<In,In,In,Out,Out> obj( In a, In b, In c, Out X, Out y);
因为第一个更清晰或更易读。
编辑
经过一番思考,我想知道这是否行得通...
class In {...}
class Out{...}
// template<typename T1 = In, typename T2 = Out>
// T1 must == type In and T2 must == type Out
class MyObject {
private:
std::vector<In*> inputs_;
std::vector<Out*> outputs_;
public:
MyObject() = deafault;
template<typename... Inputs> // would probably use move semantics or forwarding
void assignInputs(Inputs&& ... inputs);
template<typename... Outputs> // would probably use move semantics or forwarding
void assignOutputs(Inputs&& ... outputs);
};
但是,这将迫使用户必须构造对象,然后调用两个函数...我试图在构造时进行所有这些操作...
根据您的评论,我想您正在寻找类似的东西
template<typename T1, typename T2>
class MyObject {
std::vector<T1> inputs_;
std::vector<T2> outputs_;
public:
MyObject(std::vector<T1> inputs, std::vector<T2> outputs)
: inputs_(std::move(inputs)), outputs_(std::move(outputs)) { }
};
用作
MyObject<In,Out> obj({a, b, c}, {x, y});
如果您真的坚持将元素分别作为构造函数参数,那在技术上是可行的,但实现起来会更加复杂,几乎没有好处。