Frage

Ich schreibe einen einfachen Punkt-Code, während Visual Studio 10 (Beta 2) versuchen, und ich habe diesen Code getroffen, wo ich SFINAE erwarten würde in treten, aber es scheint nicht zu:

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);
}

Das gibt error C2512: 'point<T>::point' : no appropriate default constructor available

Da es sich um eine Beta ist, habe ich eine schnelle Plausibilitätsprüfung mit dem Online-Comeau Compiler, und es stimmt mit einem identischen Fehler, so scheint es, dieses Verhalten richtig ist, aber ich kann nicht sehen, warum.

In diesem Fall einiger Abhilfen sind einfach die decltype(T() / U()) inline, gibt der Punktklasse einen Standardkonstruktor oder decltype auf dem vollen Ergebnisausdruck zu verwenden, aber ich habe diesen Fehler bei dem Versuch, einen Fehler zu vereinfachen ich wurde mit einem immer Version von op_div, die nicht über einen Standardkonstruktor * verlangen, so würde ich lieber mein Verständnis von C ++ beheben, anstatt einfach nur tun, was funktioniert.

Danke!


*: das Original:

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

Welche gibt 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', und auch für die point<T> / point<U> Überlastung.

War es hilfreich?

Lösung

nicht 100% sicher. Es scheint, dass der Compiler zu instanziiert braucht beide Überlastungen, um zu bestimmen, was besser ist, aber beim Versuch, die anderen op_div mit T = int und U = point<float> zu instanziiert, dies führt zu einem Fehler, der nicht durch SFINAE (der Fehler abgedeckt wird, ist nicht, dass op_div nicht funktioniert haben ist in diesem Fall, aber diese Art kann nicht bestimmt werden).

Sie könnten versuchen, die zweite Überlastung zu deaktivieren, wenn der zweite Typ ein Punkt (boost::disable_if) ist.

Auch scheint, was zu arbeiten Rückgabetyp Erklärung verschoben (Abschaffung der op_div Struktur, aber abhängig von der C ++ 0x-Features werden von Ihrem Compiler unterstützen):

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};
}

Andere Tipps

Ich würde sagen, Ihre Fehler in hier ist:

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

Ändern Sie Ihre struct Definition folgt aus:

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

Wenn Sie einen generischen Typ T verwenden möchten, müssen Sie es in der Definition angegeben werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top