E2015
C++ Builder Programming Language
Severity: MinorWhat Does This Error Mean?
E2015 means C++ Builder found two or more overloaded functions that are equally valid candidates for a function call, and cannot choose between them. The message reads: [BCC64 Error] E2015 Ambiguity between 'func(TypeA)' and 'func(TypeB)'. Casting the argument to the exact type expected by the intended overload removes the ambiguity.
Affected Models
- C++ Builder 10.x (Alexandria)
- C++ Builder 11 (Sydney)
- C++ Builder 12 (Athens)
- RAD Studio 11 and 12
Common Causes
- A function has multiple overloads and the argument type matches more than one equally well via implicit conversion
- Passing a literal integer (e.g. 0) to a function overloaded for both int and pointer types — 0 is valid for both
- Implicit conversions exist between the types of different overloads, making the choice non-deterministic
- Using 'using' to import two namespaces that each contain a function with the same name and similar signatures
How to Fix It
-
Cast the argument to exactly the type required by the overload you intend to call.
If you mean to call func(int), write func(static_cast<int>(myVar)). If you mean to call func(double), write func(static_cast<double>(myVar)). The explicit cast removes all ambiguity.
-
If passing a literal zero and the function is overloaded for a pointer type, use nullptr instead of 0 to unambiguously select the pointer overload.
In C++11 and later, nullptr is the correct null pointer constant. Unlike 0, nullptr is not implicitly convertible to integer types, which eliminates the ambiguity.
-
If two namespaces provide conflicting overloads, remove the 'using namespace' for one of them and use fully-qualified names instead.
Importing two namespaces with identical function names is a frequent source of ambiguity in C++ Builder projects that mix VCL with third-party libraries.
Frequently Asked Questions
Can E2015 be caused by a VCL function overload conflict?
Yes — some VCL functions have overloads for both String and const char*, and passing a string literal may be ambiguous. Casting to String() or to const char* explicitly selects the intended overload.
Is E2015 always my fault?
Usually yes — the overload set is ambiguous for the argument you provided. Occasionally, a library with poorly designed overloads creates unavoidable ambiguity. In that case, an explicit cast is the practical solution even if the library design is at fault.