Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 带有模板的简单示例_C++_Templates - Fatal编程技术网

C++ 带有模板的简单示例

C++ 带有模板的简单示例,c++,templates,C++,Templates,这是一个简单的问题,我相信它以前已经被回答过了,但我似乎找不到一个好的答案 我有一门课,重点是: template<class T> Point{ \\code } 模板 点{ \\代码 } …现在我想要一个点向量,其中一些点的T是整数,而T是双精度的。我想写一些像这样的东西 template<class T> std::vector<Point<T> > points; 模板 std::向量点; 但是,遗憾的是,编译时并没有出现错误“在“

这是一个简单的问题,我相信它以前已经被回答过了,但我似乎找不到一个好的答案

我有一门课,重点是:

template<class T>
Point{
\\code
}
模板
点{
\\代码
}
…现在我想要一个点向量,其中一些点的T是整数,而T是双精度的。我想写一些像这样的东西

template<class T>
std::vector<Point<T> > points;
模板
std::向量点;
但是,遗憾的是,编译时并没有出现错误“在“模板”之前应该有一个主表达式”。我一直无法通过修改这段代码使其正常工作。另一个相关的原因是points在主类中,所以我不能将模板声明粘贴到函数之外

如果有人能给我一个解决办法,我将不胜感激


谢谢。

如果你的目标是拥有一个既包含
又包含
向量,你可以使用它

或者,如果C++11不是选项:

template<typename T> struct PointVector
{
  typedef std::vector<Point<T> > Type;
}
模板结构点向量
{
typedef std::向量类型;
}
然后:

PointVector::键入我的向量;

要获得单一类型的向量,我将使用继承:

template <typename T>
struct PointVector : public std::vector< Point<T> >
{
};

但是对于这个用例来说,这一切似乎有点过头了。除非内存非常紧张,否则我只会使用双精度向量。

一个向量只能容纳一种类型的元素。因此,您可以选择点或点,但不能将它们混合。这不应该只是
std::vector points
?您想要一个模板化的
typedef
?类模板的不同实例化是完全不相关的类型:
Point
Point
,从编译器的角度来看,是两种没有共同点的不同类型。如果您想操作相同类型的点,则需要使用公共基类。@LucTouraille:使用继承将强制OP使用引用或指针,对于“值类型”类(我假设
Point
是这样)来说,这可能不是一个好的选择。或许在这种情况下,变异方法可能更好。我不会投反对票,但在这种情况下继承是错误的,原因有几个。最重要的原因是,
std::vector
的设计目的不是公开继承自。我不确定标准是怎么说的,但我高度怀疑它是否有虚拟析构函数,这可能会导致微妙的问题。如果有的话,它应该是私有继承,但我还是不推荐它。@ereOn:谢谢你的输入。我已经使用STL容器的继承很长一段时间了,所以我很惊讶地发现它可能不安全。我对你们找到的任何支持这一点的文档都感兴趣。关于。@ereOn:我澄清了我的答案,以表明继承仅用作执行模板typedef的一种方法。标准不禁止继承自
std::vector
(显然),但它没有虚拟析构函数。也就是说,如果通过指向基类的指针
删除
一个
点向量
,可能会导致内存泄漏。此外,这种情况下的公共继承还允许OP编写
std::vector vec=PointVector()这会导致,您可能不希望这样。union解决方案更为正确,但如果选择了
boost::variant
,那就更好了。@ereOn:谢谢,我得到了你对虚拟析构函数的关注。由于继承的目的是实现模板typedef的等效性,因此子类中不会有任何数据成员,而且我也不介意切片,因为typedef应该具有等效性。您好,谢谢您的完整回答。从我的理解,Boost和C++ 11不在标准的C++库中,我编写的代码将在不必有这些包的计算机上运行。然而,我正在寻找您的第一个涉及变体的解决方案。有没有一种方法可以在没有助推的情况下做到这一点?(比如,正如另一个答案所暗示的那样。)@alexvas:如果你对深入研究Boost变体代码感到满意,那么你可能很容易复制它。或者,您也可以从Boost中提取文件(Boost有一个工具可以清晰地提取文件的子集)。Boost可以在许多平台上运行,也许您可以用自己的代码发布它(或者说服那些决定这么做的人?)
template<typename T> using PointVector = std::vector<Point<T>>; // C++11

// Now you can write:
PointVector<int> my_vector;

// Which is equivalent to:
std::vector<Point<int>> my_vector;
template<typename T> struct PointVector
{
  typedef std::vector<Point<T> > Type;
}
PointVector<int>::Type my_vector;
template <typename T>
struct PointVector : public std::vector< Point<T> >
{
};
class IntOrDouble {
    union {
        int i;
        double d;
    };
    bool is_int;
    bool is_double;
public:
    IntOrDouble () : is_int(false), is_double(false) {}
    IntOrDouble (int x) : is_int(true), is_double(false) { i = x; }
    IntOrDouble (double x) : is_int(false), is_double(true) { d = x; }
    int operator = (int x) {
        is_int = true;
        is_double = false;
        return i = x;
    };
    double operator = (double x) {
        is_int = false;
        is_double = true;
        return d = x;
    };
    operator int () const {
        if (is_int) return i;
        if (is_double) return d;
        return 0;
    }
    operator double () const {
        if (is_double) return d;
        if (is_int) return i;
        return 0;
    }
};
typedef std::vector< Point<IntOrDouble> > PointVector;