我编写了一个示例应用程序来指出我正在尝试做的事情。我有一个模板,我想对单个数据类型表现不同,并且我想从调用程序中隐藏它。在下面的代码中,目的是如果数据类型是 UnicodeString,我希望它使用我的覆盖函数;否则,我希望它使用模板。如果可能的话,修改模板并删除我的覆盖函数也可以。
如果定义了 TRY_TO_OVERRIDE_TEMPLATE,看起来编译器会放弃,因为它无法决定使用哪个模板。
如果定义了 DO_NOT_EXPLICITLY_REFERENCE_TEMPLATE,则会导致编译时错误。
如果两个定义都没有定义,它会进行字符串连接,而不是将每个字符串转换为整数并将数值相加。
顺便说一句,我正在使用当前版本的 C++ Builder。
//#define TRY_TO_OVERRIDE_TEMPLATE // results in "Unresolved external 'System::UnicodeString __fastcall MyMath::MyAddSystem::UnicodeString(System::UnicodeString, System::UnicodeString)' referenced from ...\UNIT1.OBJ" //#define DO_NOT_EXPLICITLY_REFERENCE_TEMPLATEclass MyMath {
public:
MyMath() {};
#ifdef TRY_TO_OVERRIDE_TEMPLATE
template <typename T> UnicodeString __fastcall MyAdd(UnicodeString a, UnicodeString b);
#else
UnicodeString __fastcall MyAdd(UnicodeString a, UnicodeString b);
#endif
template <typename T> T __fastcall MyAdd(T a, T b);
};
#ifdef TRY_TO_OVERRIDE_TEMPLATE
template <typename T> UnicodeString __fastcall MyAdd(UnicodeString a, UnicodeString b) {
int intA = a.ToInt();
int intB = b.ToInt();
return UnicodeString(a + b);
}
#else
UnicodeString __fastcall MyAdd(UnicodeString a, UnicodeString b) {
int intA = a.ToInt();
int intB = b.ToInt();
return UnicodeString(a + b);
}
#endif
template <typename T> T __fastcall MyMath::MyAdd(T a, T b) {
return a + b; // When defined DO_NOT_EXPLICITLY_REFERENCE_TEMPLATE, this gives standard error concatinating UnicodeStrings ([bcc32c Error] Unit1.cpp(41): invalid operands to binary expression ('const wchar_t *' and 'const wchar_t *')
}
void __fastcall TForm1::cmdRunClick(TObject *Sender)
{
UnicodeString txt;
MyMath * mth = new MyMath();
ComboBox1->Items->Add(L"1 + 3 =" + UnicodeString(mth->MyAdd<int>(1, 3)));
ComboBox1->Items->Add(L"1.1 + 3.3 =" + UnicodeString(mth->MyAdd<double>(1.1, 3.3)));
ComboBox1->Items->Add(L"2.2 + 4 =" + UnicodeString(mth->MyAdd<UnicodeString>(L"2.2", L"4"))); // result is "2.24" rather than "6"
#ifdef DO_NOT_EXPLICITLY_REFERENCE_TEMPLATE
ComboBox1->Items->Add(L"2.2 + 4 =" + UnicodeString(mth->MyAdd(L"2.2", L"4")));
#endif
}
您可以依赖标准的重载规则。如果您想要特定的 Add for Unicode 字符串,请在您已有的通用模板旁边提供一个重载,它将在编译时被选择。
#include <type_traits>
#include <string>
#include <iostream>
#include <format>
using namespace std::string_literals;
template<typename type_t>
auto add(const type_t& lhs, const type_t& rhs)
{
std::cout << "Generic add : " << lhs << " + " << rhs << "\n";;
return lhs + rhs;
}
// you can have non-template overloads too
// they will be selected in favor of the template
// when they match.
auto add(const std::string& lhs, const std::string& rhs)
{
auto result = std::format("String addition : '{}' + {}", lhs, rhs);
std::cout << result << "\n";
return result;
}
int main()
{
add(1, 2);
add("one"s, "two"s);
return 0;
}