gpt4 book ai didi

c++ - 使用SFINAE选择接口(interface)实现

转载 作者:搜寻专家 更新时间:2023-10-31 02:15:06 24 4
gpt4 key购买 nike

我正在尝试根据模板参数选择具体类实现的接口(interface)。在下面的简化示例中,有两个接口(interface)具有不同名称的方法 - Implementation类需要根据模板参数提供方法实现。

如果我使用 IntType - 它应该实现 IntInterface ( getInt()setInt(int) )。如果我使用 DoubleType - 它应该实现 DoubleInterface ( getDouble()setDouble(double) )。

为了实现这一点,我创建了一个 traits 类,它确定应使用哪个接口(interface) (InterfaceType),但还有另一个参数用于 SFINAE。

我的想法是,如果我使用例如MyTypeTrait<Type>::MyTypeInt但是相关的特征类没有 MyTypeInt定义,编译器将抛出这个可能的重载(例如 setInt() ),并使用另一个。这就是假人应该发挥作用的地方——他们有不同的论据,而且他们不是虚拟的。

但是,它不起作用。请参阅下面的编译器错误。

我正在使用 Visual Studio 2013 (VC12)。

struct IntInterface
{
virtual int getInt() const = 0;
virtual void setInt(int value) = 0;
};

struct DoubleInterface
{
virtual double getDouble() const = 0;
virtual void setDouble(double value) = 0;
};

const int IntType = 0;
const int DoubleType = 1;

template <int Type>
struct MyTypeTrait;

template <>
struct MyTypeTrait<IntType>
{
using MyTypeInt = int;
using InterfaceType = IntInterface;
};

template <>
struct MyTypeTrait<DoubleType>
{
using MyTypeDouble = double;
using InterfaceType = DoubleInterface;
};

template <int Type>
struct Implementation : public MyTypeTrait<Type>::InterfaceType
{
// Actual interface implementation for the case of IntType
virtual typename MyTypeTrait<Type>::MyTypeInt getInt() const override { return 0; }
virtual void setInt(typename MyTypeTrait<Type>::MyTypeInt value) override {}

// Dummys for SFINAE - to be used in the case of DoubleType
typename int getInt(int) const { return 0; }
void setInt() {}

// Actual interface implementation for the case of DoubleType
virtual typename MyTypeTrait<Type>::MyTypeDouble getDouble() const override { return 0.0; }
virtual void setDouble(typename MyTypeTrait<Type>::MyTypeDouble value) override {}

// Dummys for SFINAE - to be used in the case of IntType
typename double getDouble(int) const { return 0.0; }
void setDouble() {}
};


int main(int argc, char* argv[])
{
Implementation<IntType> myInt;
Implementation<DoubleType> myDouble;
}

编译器错误:

1>c++-tests.cpp(50): error C2039: 'MyTypeDouble' : is not a member of 'MyTypeTrait<0>'
1> c++-tests.cpp(26) : see declaration of 'MyTypeTrait<0>'
1> c++-tests.cpp(61) : see reference to class template instantiation 'Implementation<0>' being compiled
1>c++-tests.cpp(50): error C2146: syntax error : missing ';' before identifier 'getDouble'
1>c++-tests.cpp(50): error C2433: 'Implementation<0>::MyTypeDouble' : 'virtual' not permitted on data declarations
1>c++-tests.cpp(50): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c++-tests.cpp(50): warning C4183: 'getDouble': missing return type; assumed to be a member function returning 'int'
1>c++-tests.cpp(51): error C2039: 'MyTypeDouble' : is not a member of 'MyTypeTrait<0>'
1> c++-tests.cpp(26) : see declaration of 'MyTypeTrait<0>'
1>c++-tests.cpp(51): error C2061: syntax error : identifier 'MyTypeDouble'
1>c++-tests.cpp(55): error C2535: 'void Implementation<0>::setDouble(void)' : member function already defined or declared
1> c++-tests.cpp(51) : see declaration of 'Implementation<0>::setDouble'
1>c++-tests.cpp(50): error C3668: 'Implementation<0>::getDouble' : method with override specifier 'override' did not override any base class methods
1>c++-tests.cpp(51): error C3668: 'Implementation<0>::setDouble' : method with override specifier 'override' did not override any base class methods
1>c++-tests.cpp(42): error C2039: 'MyTypeInt' : is not a member of 'MyTypeTrait<1>'
1> c++-tests.cpp(33) : see declaration of 'MyTypeTrait<1>'
1> c++-tests.cpp(62) : see reference to class template instantiation 'Implementation<1>' being compiled
1>c++-tests.cpp(42): error C2146: syntax error : missing ';' before identifier 'getInt'
1>c++-tests.cpp(42): error C2433: 'Implementation<1>::MyTypeInt' : 'virtual' not permitted on data declarations
1>c++-tests.cpp(42): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c++-tests.cpp(42): warning C4183: 'getInt': missing return type; assumed to be a member function returning 'int'
1>c++-tests.cpp(43): error C2039: 'MyTypeInt' : is not a member of 'MyTypeTrait<1>'
1> c++-tests.cpp(33) : see declaration of 'MyTypeTrait<1>'
1>c++-tests.cpp(43): error C2061: syntax error : identifier 'MyTypeInt'
1>c++-tests.cpp(47): error C2535: 'void Implementation<1>::setInt(void)' : member function already defined or declared
1> c++-tests.cpp(43) : see declaration of 'Implementation<1>::setInt'
1>c++-tests.cpp(42): error C3668: 'Implementation<1>::getInt' : method with override specifier 'override' did not override any base class methods
1>c++-tests.cpp(43): error C3668: 'Implementation<1>::setInt' : method with override specifier 'override' did not override any base class methods

最佳答案

对于您是要支持 either/or 接口(interface)还是这 2 个接口(interface)的完整/NOP 版本的问题,我不能完全确定。

这是前者的一种解决方案。

#include <utility>
#include <type_traits>

struct IntInterface
{
virtual int getInt() const = 0;
virtual void setInt(int value) = 0;
};

template<class TrueFalse>
struct IntInterfaceImpl {};

template<>
struct IntInterfaceImpl<std::true_type> : IntInterface
{
int getInt() const override { return i_; }
void setInt(int value) override { i_ = value; }

int i_;
};

struct DoubleInterface
{
virtual double getDouble() const = 0;
virtual void setDouble(double value) = 0;
};

template<class TrueFalse>
struct DoubleInterfaceImpl {};

template<>
struct DoubleInterfaceImpl<std::true_type> : DoubleInterface
{
double getDouble() const override { return i_; }
void setDouble(double value) override { i_ = value; }

double i_;
};


enum type {
is_int,
is_double
};

template<type T>
struct Implementation
: IntInterfaceImpl<std::integral_constant<bool, T == is_int>>
, DoubleInterfaceImpl<std::integral_constant<bool, T == is_double>>
{

};


int main()
{
Implementation<type::is_int> i {};
i.setInt(6);
int a = i.getInt();

Implementation<type::is_double> d {};
d.setDouble(6.0);
int b = d.getDouble();
}

关于c++ - 使用SFINAE选择接口(interface)实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39111474/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com