[C++] 템플릿 특수화 문법에서 생략가능한...

gurumong의 이미지

템플릿 특수화 문법에 대해서 약간 의문점이 있습니다

//템플릿
template <typename InstanceType>
void Swap(InstanceType &, InstanceType &);
 
//명시적 특수화된 템플릿!? (바른 표현인지 모르겠습니다; 아니면 거꾸로? 템플릿의 명시적 특수화!?)
template<> void Swap<InstanceType>(InstanceType &, InstanceType &);

명시적 특수화된 템플릿 문법에서 함수 이름뒤의 <InstanceType> 부분은 생략 가능하다고 책에서 설명하고있는데요
생략이 가능하다는것으로 봐서 어떤 경우에 대해 쓰임이 있을꺼 같은데
책에서 이부분을 설명하지 않아서 그냥 넘어갔는데 계속 머리속을 맴돌고 꺼림직하네요

이 부분이 어떤 경우에 사용이 되고 어떤 경우에 생략할수 없는것인가요?

winner의 이미지

제가 보기에는 template과 관련된 용어에서 번역하고, 번역어를 이해하는 과정이 조금 어려워 혼돈이 오는 것 같습니다.
발제자는 어떤지 모르겠습니다만 적어도 저는 그랬습니다. 지금도 혼란을 느끼고요.

우선 template은 함수와 class 양쪽에 쓰일 수 있습니다.
말씀하신 내용은 template 함수입니다.

특화, 특수화라는 용어는 specialization이라는 용어의 번역어로 template 정의를 할 때 쓰입니다.
특화에는 두가지가 있는데 완전특화(full specialization)과 부분특화(partial specialization)이 있습니다.
하지만 template 함수는 부분특화가 불가능합니다.
그 이유는 저는 제대로 안 봤지만(^_^) http://www.gotw.ca/publications/mill17.htm 을 통해 알 수 있을 듯 합니다.

그리고 명시적이란 용어는 explicit로 원래는 type casting에 쓰였는데
template에서는 구체화(혹은 실체화: instantiation)과 함께 쓰이는 것 같습니다.
여기서 구체화란 일반화된 type으로 정의된 template이 명확한 type으로 정의된
전통적인 C++ source style로 변환되는 과정을 말하는 것으로 보이며
알기 쉽게 말하면 template 함수에서는 함수호출을 말하며, template class에서는 객체정의를 말합니다.
Template 함수는 일반화된 type으로 정의되어 명확한 type으로 정의되는 과정을 미루다가 함수호출시점에서
비로서 명확하게 함수정의가 이루어지므로 함수호출이 template을 구체화시킨다고 볼 수 있습니다.

저는 특화와 구체화가 혼돈이 왔었던 것 같습니다.
그 이유는 구체화시점에서 template의 일반환된 정의인지 혹은 어떤 type의 특화정의를 통해 구체화시킬지를
결정하기 때문에 두개의 개념이 분명히 다르다는 것을 알고 있지 않으면 혼돈이 오는 것 같습니다.
번역서를 읽고 있기 때문에 번역자가 같은 용어를 다른 두개의 번역어로 번역하고 있는지
혹은 저자가 문맥에 따라 다른 용어를 썼는지 알 수 없기 때문인 것 같습니다.
특히 '명시적 구체화'는 왠지 '완전특화'를 연상시키지요.

정리하자면 '명시적 특수화'란 용어는 없으며 말씀하신 것은 '명시적 구체화'라고 해야 할 것 같습니다.

Template 함수는 인자를 통해 type 유추가 가능할 때에 한해서 template type 인자를 생략할 수 있습니다.
생략에는 source를 읽는 독자에게 명시적으로 알려주지 못한다는 단점이 있을 수 있죠.
때에 따라서는 실수로 의도하지 않은 type으로 구체화 될 수도 있습니다.
생략의 장점은 편의성 말고도 기존 C source와의 호환성과 interface의 통일이라는
차별화된 기능을 가져옵니다.
예를 들어 C++는 pow를 template으로 구현해볼 수 있는데(실제로는 그냥 overloading으로 정의되었더군요)
pow<double>(1.0, 1.0) 이렇게 하면 기존 source와 호환이 안 되지요.
하지만 type 인자 생략을 통해 pow(1.0, 1.0)을 함으로써 source 호환을 가져옵니다.
하지만 pow(1, 1) 이렇게 하면 pow<double>인지 pow<long double> 인지
compiler는 파악할 수 없기 때문에 error를 낼 겁니다. 따라서 완전한 source 호환을 목표로 하는 것은 아닙니다.
다시 말씀드리지만 위의 설명은 예를 든 것 뿐이면 C++ pow는 일반함수 overloading으로 되어 있습니다.
Interface의 통일은 template을 심도있게 다뤄보면 알게 될 것이라 봅니다.

Template type 인자를 생략할 수 없는 경우도 있는데 template type 매개변수가
함수매개변수가 아닌 경우이지요.
http://www.cprogramming.com/tutorial/templated_functions.html 을 참고하시기 바랍니다.

ifree의 이미지

함수 템플릿을 특수화하면서 위 예의 <> 부분을 생략할 수 없는 경우가 있나요?

함수 템플릿은 부분 특수화가 되지 않으므로, 템플릿에 정의된 템플릿 파라미터를 몽땅 구체적 타입으로 명시해 주어야 하기 때문에 중복적으로 <> 부분을 또 써줄 필요는 없을 듯 합니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.