템플릿 함수는 왜 부분 특화할 수가 없을 까요?

freezm7의 이미지

Modern C++ Design 을 읽다가,
템플릿 클래스는 부분 특화 할 수 있지만

템플릿 함수는 부분 특화가 불가능하다는 것을 알았습니다.
그냥 그렇구나 하고 넘어가기엔 뭔가 석연치가 않네요.

배후에 무슨 문제가 도사리기에 템플릿 함수는 부분 특화가 되지 않는 걸까요?

아래와 같은 템플릿이 있을 때,

tempate <class T, class U>
T* create(const U& arg)
{ return new T(arg); }

다음과 같은 부분 특화는 불가능 하다는 것을 말합니다.

template <class U>
Widget* create<Widget, U>(const U& arg)
{ return new Widget(arg, -1); }
doldori의 이미지

저는 그 책을 읽어보지 않았지만 뭔가 내용을 오해하신 게 아닌가 합니다. 템플릿
함수도 부분 특화가 됩니다. 그런데 템플릿 함수를 실체화(instantiation)할 때
인자의 형으로만 type parameter를 추론하고 반환형은 고려 대상이 아닙니다.
지금 create는 인자가 하나뿐이므로 부분 특화가 무의미한 경우입니다. 다음과
같이 하면 부분 특화가 작동하는 것을 확인하실 수 있을 겁니다.

template <class T, class U> 
T* create(const T&, const U& arg) 
{ return new T(arg); } 
 
template <class U> 
Widget* create(const Widget&, const U& arg) 
{ return new Widget(arg, -1); } 
freezm7의 이미지

doldori wrote:
저는 그 책을 읽어보지 않았지만 뭔가 내용을 오해하신 게 아닌가 합니다. 템플릿
함수도 부분 특화가 됩니다. 그런데 템플릿 함수를 실체화(instantiation)할 때
인자의 형으로만 type parameter를 추론하고 반환형은 고려 대상이 아닙니다.
지금 create는 인자가 하나뿐이므로 부분 특화가 무의미한 경우입니다. 다음과
같이 하면 부분 특화가 작동하는 것을 확인하실 수 있을 겁니다.

template <class T, class U> 
T* create(const T&, const U& arg) 
{ return new T(arg); } 
 
template <class U> 
Widget* create(const Widget&, const U& arg) 
{ return new Widget(arg, -1); } 

템플릿에 대해서 보다 보니 저도 착각하고 있던 부분이 많던데요,
님이 올려주신 코드도 제가 템플릿 특화로 착각하고 있던 함수 오버로딩이죠.

다시 말해서, 아래의 함수가 위 함수의 특화가 아니라,
서로 다른 템플릿이고 단지 오버로딩인데,
우선 순위에 의해서 아래의 것이 호출되는 원리지요.
(이것도 Modern C++ Design을 보시면 나옵니다.)

그래서 결론적으로 템플릿 함수의 특화란 없는 것이죠.

다시 제가 올린 질문의 요지를 말씀드리면,

template <class T, class U>
T* create(const U& arg) { ... }

함수가 있을 때,
long* lp = create<long, int>(10);
처럼 쓸수가 있는데,

템플릿 특화를 해서, Widget 에 대해서만 다르게 동작하도록,
template <class U>
Widget* create(const U& arg) { ... }

Widget* wp = create<Widget, int>(10);

처럼 할 수는 없다는 것이죠.

근데 왜 부분특화를 굳이 막아놓았는가가 궁금하다는 것이구요.

즐겁게 살아 볼까나~*

doldori의 이미지

freezm7 wrote:

템플릿에 대해서 보다 보니 저도 착각하고 있던 부분이 많던데요,
님이 올려주신 코드도 제가 템플릿 특화로 착각하고 있던 함수 오버로딩이죠.

그렇군요. 클래스 템플릿과 함수 템플릿을 실체화하는 메커니즘이 서로 다르다는
것을 이번에 알게 되었습니다.

freezm7 wrote:

근데 왜 부분특화를 굳이 막아놓았는가가 궁금하다는 것이구요.

저도 이 점은 모르겠습니다. 아마 함수의 오버로딩과 관련이 있지 않나 싶습니다.
Design and Evolution of C++에 혹시 나오지 않을까요? '왜?'라는 질문에 대한
답은 보통 거기에 있다고 하더라구요. 당장 필요한 것은 아니어서 아직 사지는
않았는데 재미삼아 읽기는 좋을 것 같습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.