我目前有一个具有以下结构的类层次结构:
#include <list>
#include <memory>
class Base {
protected:
std::list<std::shared_ptr<Base>> items_;
Base(){}
public:
addItem(Base* derived) {
// adds derived to items_
// and checks for duplicates
}
};
class DerivedA : public Base {
public:
DerivedA() {}
}
class DerivedB : public Base {
public:
DerivedB() {}
}
我可以如下使用它们:
int main() {
DerivedA a1, a2, a3;
DerivedB b1, b2, b3;
a1.addItem(&a2); a1.addItem(&a3); a1.addItem(&b1); a1.addItem(&b2); a1.addItem(&b3);
a2.addItem(&a1); a2.addItem(&a3); a2.addItem(&b1); a2.addItem(&b2); a2.addItem(&b3);
a3.addItem(&a1); a3.addItem(&a2); a3.addItem(&b1); a3.addItem(&b2); a3.addItem(&b3);
b1.addItem(&a1); b1.addItem(&a2); b1.addItem(&a3); b1.addItem(&b2); b1.addItem(&b3);
b2.addItem(&a1); b2.addItem(&a2); b2.addItem(&a3); b2.addItem(&b1); b2.addItem(&b3);
b3.addItem(&a1); b3.addItem(&a2); b3.addItem(&a3); b3.addItem(&b1); b3.addItem(&b2);
return 0;
}
正如您所见,在::addItem()
调用中存在大量冗余。我希望能够这样使用它们:
int main() {
DerivedA a1, a2, a3;
DerivedB b1, b2, b3;
a1.addItem(&a2, &a3, &b1, &b2, &b3);
a2.addItem(&a1, &a2, &b1, &b2, &b3);
a3.addItem(&a1, &a2, &b1, &b2, &b3);
b1.addItem(&a1, &a2, &a3, &b2, &b3);
b2.addItem(&a1, &a2, &a3, &b1, &b3);
b3.addItem(&a1, &a2, &a3, &b1, &b2);
return 0;
}
所以我想在我的抽象基类中的::addItem()。。。要求如下:
我将传入对象的地址(函数接受指向对象的指针),因为基类存储了一个列表shared_ptr
这就是我迄今为止所做的尝试:
template<typename... Args, std::enable_if_t<std::is_base_of_v<Base, Args>...> { // How to use SFINAE here?
void addItem(Args*&& ... args) {
for ( auto& it : items_ ) {
// I also need to check a member variable from each of the `Args...` or derived types
// ::foo() is not shown in the above classes but exists in my code (its not important here)
// what is important is how do I expand (args) within an if statement?
if ( args->foo() == l->foo() ) {
// do something
}
// add to list
}
}
我正在尝试将我的普通成员函数转换为如上所述的行为,因为我正在考虑使用Varidiac函数模板和SFINAE来确保参数包的每个参数至少来自
Base
。
我不确定正确的语法是什么,也不确定要使用的库函数集...我尝试过使用
is_same
、is_base_of
、连接
和其他std函数模板...另一个问题是如何正确扩展if语句中的参数包。...
是否有特定的符号,或者我必须使用折叠表达式?
只需添加一个重载,并使用初始值设定项列表
:
addItem(std::initializer_list<Base*> items)
{
for(auto item: items)
addItem(item);
}
您只需使用带括号的初始化列表调用它:a1.add项目({
我正在尝试将一个参数传递给包含在主jsp中的jsp文件。从我在网上看到的使用c:set 虽然当我尝试使用包含的jsp页面中的变量时,似乎只有一个参数通过(第二个没有使用c: set) 没有崩溃,但我可以看到myArg01为空
问题内容: 我正在努力查看将值传递给函数时使用哪种方法是否有明显的优势。下面的代码可能不是解释我要做出的决定的最佳示例,但我认为这是最容易理解的示例。 可变参数方法 数组参数法 两种技术中的哪一种是首选?如果是这样,为什么(速度,可靠性或只是易于阅读)?谢谢。 问题答案: 我认为没有速度差异。因为,在功能内部,您可以像一样使用。 我认为如果参数数量较少(例如小于5个),则因为易于阅读,可能是一个更
5.7. 可变参数 参数数量可变的函数称为为可变参数函数。典型的例子就是fmt.Printf和类似函数。Printf首先接收一个的必备参数,之后接收任意个数的后续参数。 在声明可变参数函数时,需要在参数列表的最后一个参数类型之前加上省略符号“...”,这表示该函数会接收任意数量的该类型参数。 gopl.io/ch5/sum func sum(vals...int) int { total
问题内容: 我了解协方差和逆方差。但是有一件小事我无法理解。在Coursera的“ Scala中的函数式编程”课程中,Martin Ordersky提到: 函数的参数类型是互变的,而返回类型是协变的 因此,例如在Java中,让extends出现。并让一个函数为: 我有函数调用为 所以基本上就是这样。根据Wiki,协方差是“从宽到窄转换”。在上面,我们正在从狗变成动物。所以论点类型不是协变而是协变吗
局部变量 仅在代码块或函数中才可见的变量(参考函数章节的局部变量部分)。 环境变量 会影响用户及shell行为的变量。 一般情况下,每一个进程都有自己的“环境”(environment),也就是一组该进程可以访问到的变量。从这个意义上来说,shell表现出与其他进程一样的行为。 每当shell启动时,都会创建出与其环境对应的shell环境变量。改变或增加shell环境变量会使shell更新其自身的
问题内容: 该代码无法编译,编译器说f含糊。但是我认为第二种方法可以解决什么问题? 问题答案: 这是因为无法确定该方法调用是应调用变量args还是应调用float和变量args。 Java决定以这种方式来调用拓宽>装箱>变量args的方法,但是在这种情况下,两者都具有变量args。 在这种情况下,基本上将char扩展为浮动。 Java基元的扩展顺序为: