我遇到了编译问题,并将我的问题简化为以下代码块:
// implement fix point number with N-digit fraction part.
// To make example short for my question, we just use another 'k'
// to make template meaningful
template <int N>
struct fixpt {
int n;
int k;
explicit fixpt()
: k(N)
{}
explicit fixpt(int _n)
: n(_n), k(N)
{}
#ifdef BAD_EXPLICIT
explicit // <=== this is where the problem raises.
#endif
fixpt(const fixpt &rhs)
: n(rhs.n), k(N)
{}
fixpt & operator -= (const fixpt &rhs) {
n -= rhs.n;
return *this;
}
friend fixpt operator - (fixpt lhs, const fixpt &rhs)
{
lhs -= rhs;
return lhs;
}
};
// implement a (x,y) coordinated planar point.
template <typename T>
struct Point_ {
T x;
T y;
explicit Point_()
{}
explicit Point_(T _x, T _y)
: x(_x), y(_y)
{}
Point_ & operator -= (const Point_ &rhs) {
x -= rhs.x;
y -= rhs.y;
return *this;
}
friend Point_ operator - (Point_ lhs, const Point_ &rhs)
{
lhs -= rhs;
return lhs;
}
};
// implement an algorithm with any 'Point' type as its argument.
template <typename T>
Point_<T> foo(Point_<T> & pt)
{
Point_<T> a(T(1), T(2)); // <=== this is line 66, the 1st compile error
Point_<T> b(T(3), T(4));
Point_<T> A(b-a);
return Point_<T>(A.x-pt.x, A.y-pt.y);
}
int main(int argc, char *argv[])
{
Point_<fixpt<8> > x;
x.x = fixpt<8>(10);
x.y = fixpt<8>(11);
Point_<fixpt<8> > y(x);
Point_<fixpt<8> > z;
z = foo(x);
return 0;
}
定义BAD_EXPLICIT
时,代码无法编译,第一次编译错误为:main.cpp:66: error: no matching function for call to 'fixpt<8>::fixpt(fixpt<8>)'
Point_<T> a(T(1), T(2));
^
如果未定义BAD_EXPLICIT
,则代码似乎可以编译。
错误说no matching function
,但似乎我已经为fixpt<8>
定义了一个构造函数,其中包含正确的类型作为参数。
我的问题是:怎么会这样?另外,我真的很希望那个&#39;明确&#39;在那里,以防止无意使用。我怎么能这样做?
==注意:问题更新== 删除&#39;内联&#39;并使用Joachim Pileborg和Sebastian Redl建议的注入类名。 (感谢您提供有用的提示。)
答案 0 :(得分:2)
将复制构造函数显式化是一个坏主意。我不知道你的编译器到底在做什么,但是如果它被这个混淆我也不会感到惊讶。只是不要明确复制构造函数,你就没事了。
我还认为将类内联定义的函数标记为内联是一个坏主意(代码混乱);他们已经隐含内联。
最后,您可以使用C ++的注入类名称功能将fixpt<N>
替换为fixpt
定义中的fixpt
,就像使用Point_
一样。
答案 1 :(得分:1)
经过一番调查,我得到了自己问题的答案,并在此发布:
事实上,我误解了“明确”关键字的含义。请参阅我的其他问题HERE。
现在我知道'explicit'只管理参数的自动转换(包括运算符重载的函数)。通过使用'显式',我永远不能隐式或显式地使用Point_<fixpt<8> > x = y;
。例如,Point_<fixpt<8>> x = y - z;
也是非法的。甚至Point_<fixpt<8> > x(y-z)
是非法的,因为y-z
的结果会创建一个时间,比如t = y-z
。但是禁止使用类似于t = y-z
的表达式,因为相应的构造函数具有explicit
关键字。
您可能还认为此问题与THIS QUESTION重复。