我正在尝试设计一个可以从内部类构建的类。我试图实现此目的的方法是使要构建的类包含嵌套的生成器类。这种嵌套类设计对我很有吸引力,因为它会自动将我的构建器类与要构建的类相关联。
问题是,使用g ++(8.3.0)进行编译时出现以下编译器错误:field 'v' has incomplete type 'Vector'。
我提供了一个示例,说明了我遇到的问题。当然,此示例只是构建的更模糊的方法std::vector。但是,在我的项目中,我相信这种设计模式是合理的,因为builder类在替换std::vector<>::push_back方法的基础上正在做更多的工作。
我曾尝试寻找此问题的解决方案,但是我所有的结果都是关于内部和外部类成员之间的访问策略的问题,而不是关于实际上将外部类作为成员的内部类的问题。
#include <vector>
class Vector : public std::vector<int> {
public:
class Builder {
public:
Builder &add(int const i) {
v.push_back(i);
return *this;
}
Vector build() const {
return v;
}
private:
Vector v;
};
};
int main() {
Vector v = Vector::Builder().add(1).add(2).add(3).build();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以将内部构建器类移出它正在构建的类之外,但是我喜欢构建器类会自动在外部类内部作用域。
我觉得必须有一个简单的解决方案,尽管我也担心如果设法解决第一个错误,可能会遇到某种递归问题。在定义内部类之前,也许有某种方式可以“完成”外部类的定义。
任何建议表示赞赏。
我正在尝试使用 SFINAE 来限制我正在编写的类允许的模板参数类型。这是我想出的一个简单的例子,我相信它说明了我想做的事情。
我确信这个问题已经在某个地方得到了解答,但我找不到它。
以下是我发现的两种解决问题的方法:
第一(SFINAE):
template <typename T, typename = typename std::enable_if<std::is_same<T, int>::value>::type>
class Integer {
public:
T value;
};
int main() {
Integer<int> i; // Alowed
Integer<double> d; // Not allowed
Integer<double, double> dd; // Allowed (Undesired)
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢这个解决方案的是主函数中的第三个示例有效。
第二个(静态断言):
#include <type_traits>
template <typename T>
class Integer {
static_assert(std::is_same<T, int>::value, "T must be int");
public:
T value;
};
int main() {
Integer<int> i; // Allowed
Integer<double> d; // Not allowed
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我认为这个解决方案很好,但我想知道是否有更优雅或 SFINAE 的方法来完成同样的事情。 …