c ++显式关键字导致编译错误:模板类型中的模板无法解析?

时间:2015-12-04 09:43:25

标签: c++ templates

我遇到了编译问题,并将我的问题简化为以下代码块:

// 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建议的注入类名。 (感谢您提供有用的提示。)

2 个答案:

答案 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重复。