litb은 ADL이 템플릿 매개 변수는 호출 매개 변수로부터 추론 할 수 있습니다 때마다 기본적으로 어떤 일을 할 수있는 우수, 말처럼 S = ns::Identity
에 대해 arithmetic::mul
함수 템플릿을 부분적으로 특수화하여 달성 한 결과를 얻을 수 있습니다. 하지만 호출자가 ADL을 허용하는 방식으로 전화를 걸기 때문에 호출자는 std::swap
을 절대 호출하지 않습니다.
그렇다면 라이브러리 사용자가 함수 템플릿을 부분적으로 특수화해야한다고 생각합니까? 알고리즘 유형을 특수화하려는 경우 (일반적으로 알고리즘 템플릿의 경우처럼) ADL을 사용합니다. 귀하의 예제에서와 같이 정수 템플릿 매개 변수를 특수화하려고한다면 클래스에 위임해야한다고 생각합니다. 그러나 제 3자가 3을 통해 곱셈을해야한다는 것을 제 3자가 정의 할 것을 제 기대하지 않습니다. - 내 라이브러리는 모두 정수를 할 것입니다. 제 3자가 octonion에 의한 곱셈을 정의 할 것을 합리적으로 기대할 수 있습니다.
이 그것을 생각 해 내 arithmetic::mul
이 operator*
혼동을 일으킬 정도로 유사하다는 것, 그래서 내 예제에서 mul
을 전문으로하는 실제 필요가 없기 때문에, 지수는 나를 사용을위한 더 나은 예되었을 수 있습니다. 그렇다면 "아무것도의 힘에 대한 정체성은 정체성"때문에 첫 번째 매개 변수에 대해/ADL 과부하를 전문화합니다. 그래도 아이디어를 얻을 수 있기를 바랍니다.
나는 ADL에 단점이 있다고 생각한다. 이것은 네임 스페이스를 효과적으로 평평하게 만든다. ADL을 사용하여 내 수업에 arithmetic::sub
과 sandwich::sub
을 모두 구현하려는 경우 문제가 발생할 수 있습니다. 나는 전문가가 그것에 대해 무엇을 말해야하는지 모른다.
가하는 말 :
namespace arithmetic {
// subtraction, returns the difference of lhs and rhs
template<typename T>
const T sub(const T&lhs, const T&rhs) { return lhs - rhs; }
}
namespace sandwich {
// sandwich factory, returns a baguette containing lhs and rhs
template<typename SandwichFilling>
const Baguette sub(const SandwichFilling&lhs, const SandwichFilling&rhs) {
// does something or other
}
}
지금, 나는 형 ns::HeapOfHam
있습니다.
namespace ns {
HeapOfHam sub(const HeapOfHam &lhs, const HeapOfHam &rhs) {
assert(lhs.size >= rhs.size && "No such thing as negative ham!");
return HeapOfHam(lhs.size - rhs.size);
}
}
나는 또한 내 자신의 구현을 작성하는 표준 : : 스왑 스타일 ADL을 활용하려는 : 나는 산술 :: 하위 내 자신의 구현을 작성하는 표준 : : 스왑 스타일 ADL을 활용하려면 샌드위치 :: 하위 :
namespace ns {
const sandwich::Baguette sub(const HeapOfHam &lhs, const HeapOfHam &rhs) {
// create a baguette, and put *two* heaps of ham in it, more efficiently
// than the default implementation could because of some special
// property of heaps of ham.
}
}
잠시만 기다려주십시오. 나는 그것을 할 수 없다, 그렇지? 동일한 매개 변수와 다른 반환 유형을 사용하는 서로 다른 네임 스페이스의 두 가지 함수 : 일반적으로 문제가 아닌 네임 스페이스입니다. 하지만 나는 둘 다 할 수는 없다. 아마도 나는 정말 명백한 것을 놓치고 있습니다.
Btw,이 경우에는 arithmetic::sub
및 sandwich::sub
을 각각 완전히 전문화 할 수 있습니다. 발신자는 using
중 하나를 선택하고 올바른 기능을 얻습니다. 원래의 질문은 부분 전문화에 관한 것이지만, HeapOfHam을 클래스 템플릿으로 만드는 사실이 없으면 전문화가 옵션이 아닌 것처럼 할 수 있습니까?
나는 그것이 달려 있다고 생각한다. 귀하의 경우에는 'fun (u)'와 같이 호출하므로 과부하 ('N '이 매개 변수에 표시되지 않습니다) 할 수 없습니다. 그러나 "오버로딩"이 가능하다면, 그것은 선호되는 방법이라고 생각합니다. 훌륭한 예제는'std :: swap' 또는'std :: begin' 또는'std :: end' (후자의 두 가지는 C++ 0x 함수입니다)입니다. Sutter의 기사는 9 년 전에 작성되었습니다. 그가 여전히 "클래스에 위임 (delegate to class)"방법을 사용하도록 권장하는지 여부는 확실하지 않습니다. ADL에서는 작동하지 않을 것입니다. 모든 종류의 네임 스페이스를 사용하고 템플릿을 전문화해야합니다. 좋지 않음 –