我写一些简单点代码,同时试图出Visual Studio10(Β2),和我打这个代码在哪里我希望SFINAE踢,但它似乎没有:

template<typename T>
struct point {
    T x, y;
    point(T x, T y) : x(x), y(y) {}
};

template<typename T, typename U>
struct op_div {
    typedef decltype(T() / U()) type;
};

template<typename T, typename U>
point<typename op_div<T, U>::type>
operator/(point<T> const& l, point<U> const& r) {
    return point<typename op_div<T, U>::type>(l.x / r.x, l.y / r.y);
}

template<typename T, typename U>
point<typename op_div<T, U>::type>
operator/(point<T> const& l, U const& r) {
    return point<typename op_div<T, U>::type>(l.x / r, l.y / r);
}

int main() {
    point<int>(0, 1) / point<float>(2, 3);
}

这给 error C2512: 'point<T>::point' : no appropriate default constructor available

鉴于这是一个测试,我没有一个快速检查与在线科莫编译器,并且它同意有一个相同的错误,因此它似乎这种行为是正确的,但我不能看为什么。

在这种情况下一些变通办法是简单地内联的 decltype(T() / U()), ,得到点类默认的构造或使用decltype上的完整结果的表达,但我得到了这个错误,同时试图简化的一个错误我正与一个版本的op_div,并不需要一个default constructor*,所以我想修复我的理解C++而不是只是做什么工作。

谢谢!


*:将原来的:

template<typename T, typename U>
struct op_div {
    static T t(); static U u();
    typedef decltype(t() / u()) type;
};

这给 error C2784: 'point<op_div<T,U>::type> operator /(const point<T> &,const U &)' : could not deduce template argument for 'const point<T> &' from 'int', 以及 point<T> / point<U> 超载。

有帮助吗?

解决方案

不是100%肯定的。它的出现,需要编译器化这两个重载,以确定它是好的,但同时努力实例的其他op_div与 T = intU = point<float>, 这导致一个错误,不是涵盖SFINAE(错误是不是op_div没有类型在这种情况下,但该类型的无法确定)。

你可以尝试禁用的第二个重载如果第二类是一个点(boost::disable_if).

此外,似乎什么工作被推迟返回的类型宣言》(消的op_div结构,但取决于其C++0x特点是支持编译):

template<typename T, typename U>
auto
operator/(point<T> const& l, point<U> const& r) -> point<decltype(l.x / r.x)> {
    return {l.x / r.x, l.y / r.y};
}

template<typename T, typename U>
auto
operator/(point<T> const& l, U const& r) -> point<decltype(l.x / r)> {
    return {l.x / r, l.y / r};
}

其他提示

我会说你的错误是在这里:

template<typename T>
struct point {
    T x, y;
    point(T x, T y) : x(x), y(y) {}
};

改变你的结构定义:

template<typename T>
struct point<T> {
    T x, y;
    point(T x, T y) : x(x), y(y) {}
};

如果你想使用一般类型的T,你需要到指定的定义。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top