При написании Visual Studio 10 (бета-версия 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
Учитывая, что это бета-версия, я быстро проверил работоспособность с помощью онлайн-компилятора comeau, и он согласился с идентичной ошибкой, поэтому кажется, что это правильное поведение, но я не понимаю, почему.
В этом случае некоторые обходные пути - просто встроить decltype(T() / U())
, присвоить классу точки конструктор по умолчанию или использовать decltype для полного выражения результата, но я получил эту ошибку, пытаясь упростить полученную ошибку. с версией op_div, для которой не требовался конструктор по умолчанию *, поэтому я бы скорее исправил свое понимание 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>
.