문제
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())
, 포인트 클래스 A 기본 생성자를 제공하거나 전체 결과 표현식에서 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>
초과 적재.
해결책
100% 확실하지 않습니다. 컴파일러는 어느 것이 더 나은지 결정하기 위해 두 과부하를 인스턴스화해야하지만 다른 OP_DIV를 인스턴스화하는 동안 T = int
그리고 U = 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를 사용하려면 정의에 지정해야합니다.