با استفاده از ویژگی سربارگذاری چند تابع میتوانند نام یکسانی داشته باشند در حالی که تعریف پارامتر های آن های متفاوت است . این توابع میتوانند نوع خروجی متفاوت داشته باشند ولی این دلیل بر تمایر آن ها نمیشود بلکه تمایز در لیست پارامتر ها است. مثال زیر را در نظر بگیرید:
#include<iostream> using namespace std; void f(int a){ cout<<"in f(int a)"<<endl; } void f(int a,int b){ cout<<"in f(int a,int b)"<<endl; } void f(int a,double b){ cout<<"in f(int a,double b)"<<endl; } int main(){ f(1); f(1,2); f(1,2.0); return 0; } /* OUTPUT: in f(int a) in f(int a,int b) in f(int a,double a) */
در کد بالا تابغ $f$ سه بار با لیست پارامتر های مختلف تعریف شده است کامپایلر با استفاده از لیست پارامتر متوجه میشود که یک فراخوانی مربوط به کدام یک از تعاریف است. توجه کنید که تمایز در نوع خروجی منجر به سربارگذاری نمیشود بنابراین برای مثال تکه کد زیر دارای خطای کامپایلر است:
int f(int a){return 0;} double f(int a){return 0.0;}
در مواقعی کامپایلر نمیتواند موقع فراخوانی تابع مورد نظر را به طور یکتا تشخیص دهد و در نتیجه دچار ابهام شده و با خطای کامپایلر مواجه میشویم. این موضوع را در قالب مثال بررسی میکنیم.
کد زیر را در نظر بگیرید :
#include<iostream> using namespace std; void f(double a){return;} void f(float a){return;} int main(){ f(10.0); // OK ! f(10); // Compile error here ! return 0; }
در خط اول $f$ با مقداری اعشاری فراخوانی شده است که به طور پیشفرض در $C++$ از نوع $double$ در نظر گرفته شده و بدون هیچ مشکلی تابع $f$ مورد نظر با ورودی $double$ فراخوانی میشود اما در خط دوم $f$ با مقداری $int$ فراخوانی میشود و کامپایلر نمیتواند تشخیص دهد که آن را به $double$ تبدیل کند یا به $float$ و در نتیجه خطای کامپایل رخ میدهد.
این مشکل به هنگام استقاده از مقادیر پیشفرض و سربارگذاری به صورت همزمان رخ میدهد. کد زیر را درنظر بگیرید:
#include<iostream> using namespace std; void f(int a){return;} void f(int a,int b=1){return;} int main(){ f(10); // Compile error here ! return 0; }
در اینجا کامپایلر نمیتواند تشخیص دهد که منظور تابع یک پارامتری اول است یا تابع دو پارامتریی که برای متغیر دوم مقدار پیشفرض باید در نظر گرفته شود بنابراین با خطای کامپایل مواجه میشویم.