2011-03-14 66 views
2

我想递归地使用模板来定义(在编译时)一个d元组的d元组。下面的代码在Visual Studio 2010中编译得很好,但是g ++失败了,并且抱怨说它“无法直接调用构造函数”point < 1> :: point'。递归模板:在g ++下的编译错误

任何人都可以请说一说这里发生了什么?

非常感谢,乔

#include <iostream> 
#include <utility> 

using namespace std; 

template <const int N> 
class point 
{ 

private: 
    pair<double, point<N-1> > coordPointPair; 

public: 

    point() 
    { 
    coordPointPair.first = 0; 
    coordPointPair.second.point<N-1>::point(); 
    } 

}; 

template<> 
class point<1> 
{ 

private: 
    double coord; 

public: 

    point() 
    { 
    coord= 0; 
    } 

}; 

int main() 
{ 
    point<5> myPoint; 

    return 0; 
} 

回答

7

什么是你想要做的:

coordPointPair.second.point<N-1>::point(); 

看起来要显式调用point默认构造函数 - 这已经被调用的时候,构建了pair。你不能直接调用构造函数(除非你使用新的位置,这在这种情况下是没有意义的)

只需删除该行。

如果出于某种原因想从临时point<N-1>分配给它,你可以用coordPointPair.second = point<N-1>();这样做,以覆盖已建成.second

如果,一个更复杂的情况下,想参数传递给point构造函数,你可以在初始化列表中做到这一点:

point(your_type your_arg) : 
    coordPointPair(
     pair<double, point<N-1> >(0.0, point<N-1>(your_arg_here)) 
    ) 
{ 
} 
+0

MAny谢谢 - 这澄清了我的困惑/误解。 – Johannes 2011-03-15 20:17:33

2
coordPointPair.second.point<N-1>::point(); 

这是非法的。你想这样做:

coordPointPair.second = point<N-1>(); 

顺便说一句,这是没有必要的,因为这个语句的执行时,coordPointPair.second已经与point<N-1>()初始化。

但是,如果在point<>任何非默认的构造函数,那么你可以这样做:

coordPointPair.second = point<N-1>(/*arg, ...*/); //pass the arguments 

但同样,如果你这样做在初始化列表它的更好!

4

最简单的解决方案是使用初始化列表:

template <const int N> 
class point 
{ 

private: 
    pair<double, point<N-1> > coordPointPair; 

public: 

    point() : coordPointPair(std::make_pair(0.0, point<N-1>())) 
    { 
    } 

}; 

你实现什么没有C++标准兼容。如果你仍然想在构造函数中进行初始化,那么就这样做:

coordPointPair.second = point<N-1>(); 
+0

我会删除'make_pair'调用。只需使用两个参数'pair'构造函数即可。 – aschepler 2011-03-14 16:07:40

+0

@aschepler我也是,但这个例子可能会被简化以证明问题。点的实际构造函数可能更复杂,甚至需要参数 – 2011-03-14 16:09:04

+0

是的,您是对的 - 这是一个简化的示例;真正的构造函数确实需要参数。 – Johannes 2011-03-15 20:18:33