[C++ 문법] template class가 있을 때, 해당 클래스의 member fuction을 다른 template class와 함께 specialization하기?

kiwon의 이미지

template <typename T>
class Vector {
  ...
}
 
template <typename T>
class Field {
  ...
  void out() const;
};

위와 같이 템플릿 클래스들이 있을 때, 보통 특정 타입에 대하여 member function을 specialization 할 경우 아래와 같이 합니다.
template <>
void Field<double>::out() const {
 ...
}
 
template <>
void Field<int>::out() const {
 ...
}

그런데 specialization하려는 대상의 타입이 아래와 같은 의도로, template type을 커버하도록 해야하는 경우 어떻게 하나요?
template <>
void Field< Vector<T> >::out() const {
 ...
}
winner의 이미지

Modern C++ Design에서 봤던 기억이 있군요. 써본 적은 없습니다만...
만일 다른 언어에 대해서 경험이 적으시다면 슬슬 다른 언어를 공부해보라고 권유하고 싶습니다.

C++ 처럼 ALGOL 계열 언어이면서 동적 type 언어 중 가장 C++ 느낌을 주었던게 Python이더군요.

neogeo의 이미지

질문하신 내용은 정확히는 member function 의 특수화가 아니라 해당 class 의 특수화에 해당합니다.

해당하는 member function 이 template function 이 아니기 때문이지요.

template <typename T>
class Field< Vector<T> >
{
   void out() const {
     ...
   }
};

로 해주시면 깔끔하게 처리 됩니다. Field Class 를 한번 더 특수화 해주는 느낌으로 해주시면 됩니다.

Neogeo - Future is Now.

Neogeo - Future is Now.

kiwon의 이미지

답변 고맙습니다. 그렇죠. 엄밀히는 class specialization 입니다. 그런데, 조언하신대로 하게되면 해당 Field class에서 Vector에 대해 다른 member function들도 정의해야 하는 번거로움(?)이 생기게 됩니다. 특정 member function만 type dependent한 작업을 하도록 하고 싶은데 말이죠.

사실 virtual member function과 base class를 이용하여 polymorphism을 구현하면 해결됩니다. 실제로도 현재 그렇게 작성해 두었구요. 그런데 member function만 specialization하는 것이 가능하다면 (이것을 template class specialization이라 불러야할지 template class member function specialization이라 해야할지는 좀 논의가 필요하겠습니다만) 이를 이용하되, template type을 specialization에 이용할 수 있는가가 궁금했습니다.

neogeo의 이미지

원하시는게 원래 질문하신 내용보다 조금 복잡하군요.

이런 방법이 옳은지는 모르겠지만 말씀하신 방법이외에 다른 방법으로는

특수화를 아예 쓰지말고 원래 function 에서 runtime 에 typeid 를 분리해낸뒤 typeid 의 앞부분이 template vector class 의 앞부분의 글자수와 일치하면 분기하는 방법도 있을거 같습니다.

Neogeo - Future is Now.

Neogeo - Future is Now.

winner의 이미지

Field<int> f_int;
f_int.out(); // template <> void Field<int>::out() const 호출
Filed< Vector<int> > f;
f.out(); // template <> void Field< Vector<T> >::out() const 호출?

쉽지 않을 것 같네요.

winner의 이미지

#include <iostream>
using namespace std;
 
 
template <typename T>
class Vector
{
};
 
template <typename T>
class Field
{
public:
    void out() const;
};
 
template <typename T>
class Field< Vector<T> > : public Field<T>
{
public:
    void out() const
    {
        cout << "Field_Vector" << endl;
    }
};
 
template <>
void Field<double>::out() const
{
}
 
template <>
void Field<int>::out() const
{
    cout << "field_int" << endl;
}
 
int main()
{
    Field<int> f;
    f.out();
    Field< Vector<int> > fv;
    fv.out();
}
 
 
 
결과
field_int
Field_Vector

template class specialization이라는 neogeo님의 말씀을 듣고 좀 연구해봤습니다.
작업하다보니 http://kldp.org/node/115752 이글이 떠오르더군요.
원하시는 결과인지 잘 모르겠습니다.
이래서야 Field라는 이름만 공유하는 것 뿐이라서 혼란만 가중되는 것 같군요

예전에 Visual C++의 ATL CString을 예외로 날렸더니 MFC CString으로 잡을려고 하다가 실패해서 원인을 찾느라고 고생했던 기억이 나네요.

winner의 이미지

위 source는 완전 실패작....

댓글 달기

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