在C++中,是否可以覆盖模板中的单个数据类型

问题描述 投票:0回答:1

我编写了一个示例应用程序来指出我正在尝试做的事情。我有一个模板,我想对单个数据类型表现不同,并且我想从调用程序中隐藏它。在下面的代码中,目的是如果数据类型是 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
}
c++ templates c++builder
1个回答
0
投票

您可以依赖标准的重载规则。如果您想要特定的 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;
}
© www.soinside.com 2019 - 2024. All rights reserved.