c++ - Using SFINAE to select the interface to implement -


i'm trying select interface concrete class implements based on template parameter. in simplified example below there 2 interfaces methods of different names - implementation class needs provide method implementations, depending on template parameter.

if use inttype - should implement intinterface (getint() , setint(int)). if use doubletype - should implement doubleinterface (getdouble() , setdouble(double)).

in order achieve this, created traits class determines interface should used (interfacetype), has parameter used sfinae.

the idea if use e.g. mytypetrait<type>::mytypeint relevant trait class has no mytypeint definition, compiler throw possible overload (for e.g. setint()), , use one. that's dummys should kick in - have different arguments , they're not virtual.

however, doesn't work. see below compiler errors.

i'm using 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 case of inttype     virtual typename mytypetrait<type>::mytypeint getint() const override { return 0; }     virtual void setint(typename mytypetrait<type>::mytypeint value) override {}      // dummys sfinae - used in case of doubletype     typename int getint(int) const { return 0; }     void setint() {}      // actual interface implementation case of doubletype     virtual typename mytypetrait<type>::mytypedouble getdouble() const override { return 0.0; }     virtual void setdouble(typename mytypetrait<type>::mytypedouble value) override {}      // dummys sfinae - used in 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; } 

compiler errors:

1>c++-tests.cpp(50): error c2039: 'mytypedouble' : not member of 'mytypetrait<0>' 1>          c++-tests.cpp(26) : see declaration of 'mytypetrait<0>' 1>          c++-tests.cpp(61) : see reference 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++ not support default-int 1>c++-tests.cpp(50): warning c4183: 'getdouble': missing return type; assumed member function returning 'int' 1>c++-tests.cpp(51): error c2039: 'mytypedouble' : not 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 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 override specifier 'override' did not override base class methods 1>c++-tests.cpp(51): error c3668: 'implementation<0>::setdouble' : method override specifier 'override' did not override base class methods 1>c++-tests.cpp(42): error c2039: 'mytypeint' : not member of 'mytypetrait<1>' 1>          c++-tests.cpp(33) : see declaration of 'mytypetrait<1>' 1>          c++-tests.cpp(62) : see reference 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++ not support default-int 1>c++-tests.cpp(42): warning c4183: 'getint': missing return type; assumed member function returning 'int' 1>c++-tests.cpp(43): error c2039: 'mytypeint' : not 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 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 override specifier 'override' did not override base class methods 1>c++-tests.cpp(43): error c3668: 'implementation<1>::setint' : method override specifier 'override' did not override base class methods 

i wasn't sure question whether wanted support either/or interface or complete/nop version of 2 interfaces.

here 1 solution former.

#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.setint(6);     int = i.getint();      implementation<type::is_double> d {};     d.setdouble(6.0);     int b = d.getdouble(); } 

Comments

Popular posts from this blog

mysql - Dreamhost PyCharm Django Python 3 Launching a Site -

java - Sending SMS with SMSLib and Web Services -

java - How to resolve The method toString() in the type Object is not applicable for the arguments (InputStream) -