我有一個帶有 3 個模板引數的類定義。我想用兩個引數的特定組合創建這個類的專業化,留下第三個引數。如何在不重復代碼的情況下做到這一點?
template < typename A, typename B, class C> Foo{}; // only defining particular specializations
template<class C> Foo<int, float, C>
{
int V1;
float V2;
friend C;
/* implementation using V1, V2 */
}
template<class C> Foo<bool, char, C>
{
bool V1;
char V2;
friend C;
/* duplicate implementation using V1, V2 */
}
main {
Foo<bool, char someclassname> fbc;
Foo<int, float, otherclassname> fif;
}
uj5u.com熱心網友回復:
你可以使用概念
// or simply drop this if you don't need it
template <typename A, typename B, class C>
struct Foo{};
template<typename A, typename B, class C>
requires std::same_as<A,int> && std::same_as<B,float>
|| std::same_as<A,bool> && std::same_as<B,char>
struct Foo<A, B, C>
{
A V1;
B V2;
friend C;
/* implementation using V1, V2 */
};
或從公共基類繼承
template <typename A, typename B, class C>
struct Foo{};
template <typename A, typename B, class C>
struct Foo_impl
{
A V1;
B V2;
friend C;
/* implementation using V1, V2 */
};
template<class C>
struct Foo<int,float,C>:Foo_impl<int,float,C>{};
template<class C>
struct Foo<bool,char,C>:Foo_impl<int,float,C>{};
如果你不需要默認情況,你也static_assert可以
template <typename A, typename B, class C>
struct Foo{
static_assert(std::is_same_v<A,bool> && std::is_same_v<B,char>
|| std::is_same_v<A,int> && std::is_same_v<B,float>);
A V1 = 10;
B V2;
friend C;
/* implementation using V1, V2 */
};
uj5u.com熱心網友回復:
我上面的原始問題不夠詳細,沒有編譯。我發現解決方案是上述建議的組合。感謝所有回應者。在這里,我發布了完整的示例。該類旨在為跨元件作業的插件實作引數類。我知道本機 RTTI 在這種情況下不起作用(Linux 是這樣嗎?)所以我實作了一個簡單的型別識別。插件類將匯出指向 Base 類的指標,然后在鏈接后將其重新轉換為正確的 Numeric 型別。
#include <type_traits>
#include <concepts>
enum class TypeID: int { INTEGER=1, FLOAT};
// abstract base class, defines interface for a RTTI mechanism
class Base
{
public:
Base() {};
virtual ~Base() {};
virtual TypeID GetID() = 0; // RTTI
};
template< typename V, TypeID ID, class F>
class Numeric : public Base
{
static_assert(
(std::same_as<V, int> && TypeID::INTEGER ==ID) ||
(std::same_as<V, float> && TypeID::FLOAT == ID)
, "Error message here");
friend F;
public:
Numeric(V argValue=0) { V1 = argValue; };
virtual ~Numeric(){};
TypeID GetID() { return ID; }
V GetValue() { return V1; }
protected:
V V1=0;
void SetValue(V argValue) { V1 = argValue; }
};
template <class F> using NumericInt = Numeric<int, TypeID::INTEGER, F>;
template <class F> using NumericFloat= Numeric<float, TypeID::FLOAT, F> ;
class FriendlyClass {
public:
FriendlyClass(int argInitial) { mN.SetValue(argInitial); };
private:
NumericInt<FriendlyClass> mN= NumericInt<FriendlyClass>();
};
int main(){
NumericInt<FriendlyClass> N1(1); // OK
NumericFloat<FriendlyClass> N2(2); // OK
Numeric<int, TypeID::INTEGER, FriendlyClass> N3(3); // same as alias NumericInt , but OK
Numeric<int, TypeID::FLOAT, FriendlyClass> N4(4); // NOT ok, will static_assert()
return 0;
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/380299.html
上一篇:可變引數模板呼叫assert()
