انجمن‌های فارسی اوبونتو

لطفاً به انجمن‌ها وارد شده و یا جهت ورود ثبت‌نام نمائید

لطفاً جهت ورود نام کاربری و رمز عبورتان را وارد نمائید


ارائه ۲۴٫۱۰ اوبونتو منتشر شد 🎉

نویسنده موضوع: template ها در ++C  (دفعات بازدید: 1582 بار)

0 کاربر و 1 مهمان درحال مشاهده موضوع.

آفلاین احسان فعالپور

  • Sr. Member
  • *
  • ارسال: 408
  • جنسیت : پسر
template ها در ++C
« : 02 شهریور 1394، 12:27 ب‌ظ »
سلام.
من برای یه قسمتی از کدم بایستی چندتا تابع بنویسم که مربوط به کار با چند جمله ای هاست.
یکی از این توابع قراره درجه چند جمله ای رو زیاد کنه.مثلا در جه 2 بهش بدیم و بگیم درجه رو 3 تا زیاد کن.این تابع اونقدری صفر پشت این این چند جمله ای بذاره که هم سایز یه چند جمله ای درجه 5 بشه.
برای محاسبات ماتریسی از کتابخانه armadillo استفاده میکنم و کد زیر رو نوشتم که متاسفانه چون زیاد به template ها مسلط نیستم نمیدونم ایرادش کجاست که ارور میده.

template<typename T>
auto shiftPolynomial(const Col<T>& input, const int& howMuch,
    const VectorType& WhichType) ->Col<T> {
  Col<T> result(input.n_elem + howMuch);
  if (WhichType == VectorType::ComplexType) {
    if (howMuch > 0) {
      vector<complex<double>> tmp(input.n_elem + howMuch);
      for (size_t index = 0; index < howMuch; index++) {
        tmp[index] = 0.0;
      }
      for (size_t index = howMuch; index < tmp.size(); index++) {
        tmp[index] = input(index - howMuch);
      }
      copy_n(tmp.begin(),tmp.size(),result.begin());
    } else {
      return input;
    }
  } else if (WhichType == VectorType::OrdinaryType) {
    if (howMuch > 0) {
      vector<double> tmp(input.n_elem + howMuch);
      for (size_t index = 0; index < howMuch; index++) {
        tmp[index] = 0.0;
      }
      for (size_t index = howMuch; index < tmp.size(); index++) {
        tmp[index] = input(index - howMuch);
      }
      copy_n(tmp.begin(),tmp.size(),result.begin());
    } else {
      return input;
    }
  }
  return result;
}

int main() {
  cx_vec N { { 1, 2 }, { 3, 4 } };

  vec D{1,2,3};
  cout << shiftPolynomial(D,3,VectorType::OrdinaryType) << endl;
  return 0;
}

ایرادش اینجاست که بسته به نوعی که با enum براش مشخص میکنم بایستی فقط همون قسمت از تابع رو انجام بده ولی ظاهرا به قسمتهای دیگه if هم میره و اینجا عدم تطابق پیش میاد بین نوعی که باید باشه و قسمتی که الان برنامه توشه.
ارور توی copy_n رخ میده و میگه که نمیتونه نوع complex رو به double تبدیل کنه.
آیا قوانین خاصی دارند این template ها؟
ممنون میشم راهنماییم کنید.


با تشکر
عضو ارشد فدراسیون بیکاران ایران FBI

آفلاین alend

  • High Hero Member
  • *
  • ارسال: 1319
پاسخ : template ها در ++C
« پاسخ #1 : 02 شهریور 1394، 03:11 ب‌ظ »
این اولین سوال درست حسابی برنامه نویسی است که در انجمن دیدم!

به complex واقعا نیاز داری. من با armadillo و template ها کار کردم ولی الان وقت ندارم کدتو چک کنم (امید وارام تا آخر هفته یه کم وقتم آزادشه هر چند که امیدوارم یک نفر دیگر جوایتو زودتر بدهد :).

با c++ 11 کامپایل می کنی به علت وجود auto می پرسم که یک کلمه کلیدی جدید است و مفهومش با auto سی فرق می کند.
« آخرین ویرایش: 02 شهریور 1394، 03:14 ب‌ظ توسط alend »

آفلاین احسان فعالپور

  • Sr. Member
  • *
  • ارسال: 408
  • جنسیت : پسر
پاسخ : template ها در ++C
« پاسخ #2 : 02 شهریور 1394، 03:33 ب‌ظ »
این اولین سوال درست حسابی برنامه نویسی است که در انجمن دیدم!

به complex واقعا نیاز داری. من با armadillo و template ها کار کردم ولی الان وقت ندارم کدتو چک کنم (امید وارام تا آخر هفته یه کم وقتم آزادشه هر چند که امیدوارم یک نفر دیگر جوایتو زودتر بدهد :).

با c++ 11 کامپایل می کنی به علت وجود auto می پرسم که یک کلمه کلیدی جدید است و مفهومش با auto سی فرق می کند.

سلام
بله به نوع complex نیاز دارم و اصرارم برای استفاده از template ها به این خاطره که کمتر کد ینویسم، منتها چون  ویژگی های vec و cx_vec با هم متفاوته پس مجبورم یه جوری (که اینجا فقط enum ها به ذهنم رسید) مسیر تابع رو بسته به نوع ورودی عوض کنم،که ظاهرا به خاطر دانش کم نتونستم خوب قضیه رو هندل کنم.
عضو ارشد فدراسیون بیکاران ایران FBI

آفلاین امید توانا

  • Hero Member
  • *
  • ارسال: 981
  • جنسیت : پسر
پاسخ : template ها در ++C
« پاسخ #3 : 02 شهریور 1394، 11:10 ب‌ظ »
اولین توصیه: صرفا به این دلیل که سی پلاس پلاس امکان هر کاری به شما میده دلیل خوبی نیست بر اینکه از هر چیزی استفاده کنید. templateها در سی پلاس پلاس باید با دلیل موجه مورد استفاده قرار بگیره. یکی از این دلایل مثلا تابع سورت و یا ماکس و مین است

template<typename T>
auto max(T a, T b)
{
if (a > b)
return a;
return b;
}

در اینجا شما می تونید ماکس هر دو شیی از یک نوع رو بدست بیارید مادامی که عملگر < رو برای اون شیی بازنویسی کنید. ولی در کد شما عملا ۲ نوع شیی دارید که بهتره دو تابع مجزا بنویسید، چون که در تابع شما یک مقایسه هم انجام میشه و عملا کد شما کوچک که نشده هیچ، یک مقایسه هم در زمان اجرا برای هر بار فراخوانی تابع محاسبه میشه.

اما در مورد مشکل شما، در زمان کمپایل شما تابع shiftPolynomial رو فراخونی میکنید و کمپایلر یک نسخه از فانکشن تمپلیتی شما رو برای vec D{1,2,3} به عنوان T میسازه.
tmp از نوع vector<complex<double>> است که تابع copy_n(tmp.begin(),tmp.size(),result.begin()) قادر نیست مقادیر Col<T> (با T همان مقدار vec رو cast کنه و در اون قرار بده. ربطی به تمپلیت نداره و کمپایلر در هر دو قسمت if وارد نمیشه. حتی در یک قسمتش هم مشکل پیدا میکنه.
مسلما کمپایلر باید در هر دو قسمت شرط وارد بشه و کد قابل فهم ماشین رو درست کنه. در زمان اجراست که برنامه فقط به یکی از قسمتهای شرط فقط وارد میشه.
« آخرین ویرایش: 03 شهریور 1394، 06:31 ب‌ظ توسط امید توانا »

آفلاین احسان فعالپور

  • Sr. Member
  • *
  • ارسال: 408
  • جنسیت : پسر
پاسخ : template ها در ++C
« پاسخ #4 : 02 شهریور 1394، 11:25 ب‌ظ »
نظرتون در مورد tmp اشتباهه (من اینطور فکر میکنم لا اقل)
چون tmp در دو قسمت تعریف شده و اینجا بر اساس پارامترهای ورودیه تابع اصلا به if اول وارد نمیشیم و در قسمت دوم که بناست مسیر اجرای تابع باشه tmp دیگه از نوعی که شما گفتی نیست.
عضو ارشد فدراسیون بیکاران ایران FBI

آفلاین امید توانا

  • Hero Member
  • *
  • ارسال: 981
  • جنسیت : پسر
پاسخ : template ها در ++C
« پاسخ #5 : 03 شهریور 1394، 06:35 ب‌ظ »
پست بالا اصلاح شد.