조건에 따라 리턴타입이 다른 함수 만들기?

jinserk의 이미지

예를 들어서,

template <typename T>
class A {
   A<T>* t1_ptr;
   T*    t2_ptr;
   bool flag;
 
public:
 
   (T1& or T2&) operator[](int idx) {
       if (flag)
           return t1_ptr[idx];
       else
           return t2_ptr[idx];
   }

위와 같은 클래스가 있다고 할때요.
멤버함수의 리턴 타입을 내부 조건에 따라 다르게 주어야 할 필요가 생겼습니다.
operator[] 가 unitary parameter 라서 function overriding 도 못할 듯 싶구요.
뭔가 좋은 꽁수가 없을까요?

sev314의 이미지

복합체 패턴(composite pattern)을 써봤습니다.

그런데 제가 코드의 의도를 잘 파악했는지 모르겠습니다.

이런 걸 의도하신 것 맞습니까?

#include <iostream>
#include <utility>
#include <memory>
#include <vector>
 
using namespace std;
 
template <typename T>
class A {
    private:
        vector< A<T> > *t1;
        T *t2;
        bool flag;
 
    public:
        A<T> &operator[](int idx) { return t1->at(idx); }
 
        A(bool flag = false) : flag(flag) {
            if (flag)
            {
                t1 = new vector< A<T> >();
                t2 = 0;
            }
            else
            {
                t1 = 0;
                t2 = new T();
            }
        }
        ~A() {
        }
 
        bool is_vec() const { return flag; }
 
        operator T() const { return *t2; }
 
        A<T>& operator =(const T& rhs) {
            (*t2) = rhs;
            return *this;
        }
 
        A<T>& operator =(const A<T>& rhs) {
            A<T>& lhs = *this;
 
            if (rhs.t1)
                lhs.t1   = new vector< A<T> >(*(rhs.t1));
            if (rhs.t2)
                lhs.t2   = new T(*(rhs.t2));
            lhs.flag = rhs.flag;
 
            return lhs;
        }
 
        size_t size() const {
            return t1->size();
        }
 
        void resize(size_t size) {
            t1->resize(size);
        }
};
 
int main()
{
    A<int> l1(false);
    A<int> l2(false);
    A<int> l3(false);
    A<int> l4(false);
    A<int> l5(false);
    A<int> c1(true);
    A<int> c2(true);
 
    l1 = 71;
    l2 = 10;
    l3 = 9;
    l4 = 17;
    l5 = 20;
 
    c1.resize(3);
    c1[0] = l1;
    c1[1] = l2;
    c1[2] = l3;
 
    c2.resize(3);
    c2[0] = l4;
    c2[1] = l5;
    c2[2] = c1;
 
    cout << c2[0] << endl;
    cout << c2[1] << endl;
    cout << c2[2][0] << endl;
    cout << c2[2][1] << endl;
    cout << c2[2][2] << endl;
 
    return 0;
}
 
// EOF

jinserk의 이미지

직접 코딩까지 해주시니 정말 감사드립니다.

원래 의도는 아래와 같은 코드였습니다.

template <typename T>
class A
{
    private:
        A<T>* pcontainer_;
        T*    pelement_;
        bool  is_container_;
 
    public:
        A(int s1) {
            set(s1);
        }
 
        A(int s1, int s2) {
            set(s1, s2);
        }
 
        void set(int s1) {
            is_container_ = false;
            pcontainer_ = NULL;
            pelement_ = new T [s1];
        }
 
        void set(int s1, int s2) {
            is_container_ = true;
            pcontainer_ = new A<T> [s1];
            pelement_ = NULL;
 
            for (int i = 0; i < s1; i++)
                pcontainer_[i].set(s2);
        }
 
        (????) operator[] (int idx) {
            if (is_container_)
                return pcontainer_[idx];
            else
                return pelement_[idx];
         }
 
};

올려주신 코드와 제 의도한 코드를 놓고 비교해보니,
저는 A 의 하위를 1차원 벡터로 생각했던 것에 비해
올려주신 코드는 하위를 원소 하나하나로 생각하는데 차이가 있는 듯 합니다.
생각해보니 캐스트연산자를 적절히 쓰면 될것도 같네요.
좋은 힌트를 주셔서 정말 감사합니다.

Leo.

댓글 달기

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