انجمنهای فارسی اوبونتو
کمک و پشتیبانی => برنامهسازی => نویسنده: احسان فعالپور در 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 ها؟
ممنون میشم راهنماییم کنید.
با تشکر
-
این اولین سوال درست حسابی برنامه نویسی است که در انجمن دیدم!
به complex واقعا نیاز داری. من با armadillo و template ها کار کردم ولی الان وقت ندارم کدتو چک کنم (امید وارام تا آخر هفته یه کم وقتم آزادشه هر چند که امیدوارم یک نفر دیگر جوایتو زودتر بدهد :).
با c++ 11 کامپایل می کنی به علت وجود auto می پرسم که یک کلمه کلیدی جدید است و مفهومش با auto سی فرق می کند.
-
این اولین سوال درست حسابی برنامه نویسی است که در انجمن دیدم!
به complex واقعا نیاز داری. من با armadillo و template ها کار کردم ولی الان وقت ندارم کدتو چک کنم (امید وارام تا آخر هفته یه کم وقتم آزادشه هر چند که امیدوارم یک نفر دیگر جوایتو زودتر بدهد :).
با c++ 11 کامپایل می کنی به علت وجود auto می پرسم که یک کلمه کلیدی جدید است و مفهومش با auto سی فرق می کند.
سلام
بله به نوع complex نیاز دارم و اصرارم برای استفاده از template ها به این خاطره که کمتر کد ینویسم، منتها چون ویژگی های vec و cx_vec با هم متفاوته پس مجبورم یه جوری (که اینجا فقط enum ها به ذهنم رسید) مسیر تابع رو بسته به نوع ورودی عوض کنم،که ظاهرا به خاطر دانش کم نتونستم خوب قضیه رو هندل کنم.
-
اولین توصیه: صرفا به این دلیل که سی پلاس پلاس امکان هر کاری به شما میده دلیل خوبی نیست بر اینکه از هر چیزی استفاده کنید. 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 وارد نمیشه. حتی در یک قسمتش هم مشکل پیدا میکنه.
مسلما کمپایلر باید در هر دو قسمت شرط وارد بشه و کد قابل فهم ماشین رو درست کنه. در زمان اجراست که برنامه فقط به یکی از قسمتهای شرط فقط وارد میشه.
-
نظرتون در مورد tmp اشتباهه (من اینطور فکر میکنم لا اقل)
چون tmp در دو قسمت تعریف شده و اینجا بر اساس پارامترهای ورودیه تابع اصلا به if اول وارد نمیشیم و در قسمت دوم که بناست مسیر اجرای تابع باشه tmp دیگه از نوعی که شما گفتی نیست.
-
پست بالا اصلاح شد.