是否可以根据c ++ 添加

问题描述

我希望可以根据模板args更改类成员。 我想要类似的东西

template<int value>
class MyClass
{
public:
   void print()
   {
      // using the member
      std::cout << sizeData() << std::endl;
      for (int i=0;i<sizeData();i++)
      {
         std:cout << data[i] << std::endl;
      }
   }
   static int sizeData()
   {
     #if value == 1
        return 3;
     #endif
     #if value == 2
        return 6;
     #endif
   }
   static int sizeArray()
   {
     #if value == 1
        return 40;
     #endif
     #if value == 2
        return 200;
     #endif
   }
private:
   #if value == 1
      int data[3];
      const static int array[40];
   #endif
   #if value == 2
      int data[6];
      const static int array[200];
   #endif
}

我不知道它可以用c ++实现。

感谢您的时间。

添加

许多先生已经在C ++ 11和C ++ 17中给出了答案。感谢您的所有建议。

如果代码可以在C ++ 98中解决,那将是完美的。因为我的代码应该在仅支持C ++ 98的平台上运行。

解决方法

您可以使用std::conditional选择您想要的成员

template<int value>
class MyClass
{
public:
   static int sizeData()
   {
       return (value == 1) ? 3 : 6; // needs to be improved
   }
   static int sizeArray()
   {
       return sizeof(array) / sizeof(array[0]);  // size of array divided by size of element is then number of elements in the array
   }
private:

   std::conditional_t<value == 1,int[3],int[6]> data;
   const static std::conditional_t<value == 1,int[40],int[200]> array;

};

尽管std::conditional不是C ++ 98的一部分,但仅使用C ++ 98 C ++实现,因此您可以使用参考站点链接中的可能实现。您可以看到使用它

#include <iostream>

template<bool B,class T,class F>
struct conditional { typedef T type; };
 
template<class T,class F>
struct conditional<false,T,F> { typedef F type; };

template<int value>
class MyClass
{
public:
    static int sizeData()
    {
       return (value == 1) ? 3 : 6; // needs to be improved
    }
    static int sizeArray()
    {
       return sizeof(array) / sizeof(array[0]);
    }
private:

    typename conditional<value == 1,int[6]>::type data;
    const static typename conditional<value == 1,int[200]>::type array;

};

int main()
{
    MyClass<1> m;
    std::cout << m.sizeData();
}

在此live example中。


由于sizeData不是data,而函数是static,因此这种情况对于std::conditional来说是分散的。为了避免代码重复,我们可以使用枚举技巧来获取数组大小的编译时间常数,而不必使用#include <iostream> template<int value> class MyClass { public: static int sizeData() { return data_size; // now improved } static int sizeArray() { return array_size; } private: enum { data_size = (value == 1) ? 3 : 6 }; // this is required to be a compile time constant enum { array_size = (value == 1) ? 40 : 200 }; // these need to become before the array members int data[data_size]; // less verbose const static int array[array_size]; }; int main() { MyClass<1> m; std::cout << m.sizeData(); }

from pywurfl.wurfl import Wurfl

# Create a WURFL Engine. Please note that the installed wurfl.zip path may change.
# for example,on OS X systems,it will be in `/usr/local/share/wurfl/wurfl.zip`
# on Linux systems,it will be in `/usr/share/wurfl/wurfl.zip`.
wurfl = Wurfl('/usr/share/wurfl/wurfl.zip')

# Lookup an HTTP request
http_request = {
    "accept-encoding": "gzip,deflate,br","accept-language": "en-US,en;q=0.9","accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp","user-agent": " Mozilla/5.0 (Linux; Android 10; SM-G981U1) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36",}
dev = wurfl.parse_headers(http_request)

# You can also lookup a device with just the user-agent string
# dev = wurfl.parse_useragent(user_agent)

# retrieve some properties and capabilities values

# WURFL device ID:
print("device id =",dev.id)

# Some static capabilities:
static_capabilities = ["model_name","brand_name","device_os"]

# Retrieve the value of a single static capability:
print("get_capability('model_name') =",dev.get_capability(static_capabilities[0]))

# Retrieve the value of many static capabilities at once:
print("get_capabilities(static_capabilities) =",dev.get_capabilities(static_capabilities))

# Some virtual capabilities:
virtual_capabilities = ["complete_device_name","form_factor"]

# Retrieve the value of a single virtual capability:
print("get_virtual_capability('complete_device_name') =",dev.get_virtual_capability(virtual_capabilities[0]))

# Retrieve the value of many virtual capabilities at once:
print("get_virtual_capabilities(virtual_capabilities) =",dev.get_virtual_capabilities(virtual_capabilities))

# Make sure you release the device when you are finished
dev.release()
,

您需要将条件逻辑移动到本地化位置。 static inline constexpr变量是您的朋友,如果可以选择C ++ 17:

template<int value>
class MyClass
{
private:
   inline static constexpr int data_size = (value == 1) ? 3 : 6;
   inline static constexpr int array_size = (value == 1) ? 40 : 200;

public:
   static int sizeData() { return data_size; }
   static int sizeArray() {return array_size; }

private:
      int data[data_size];
      const static int array[array_size];  
};

如果用于计算大小的逻辑需要更复杂,则始终可以编写一个constexpr函数以给定value作为(非模板)参数来计算它。

,

由于您使用的是C ++ 98,因此必须使用template specialization

template<int value>
class MyClass
{
};

template<>
class MyClass<1>
{
public:
   int sizeData()
   {
       return 3;
   }

   int sizeArray()
   {
       return 40;
   }
private:
   int data[3];
   const static int array[40];
};

template<>
class MyClass<2>
{
public:
   int sizeData()
   {
       return 6;
   }

   int sizeArray()
   {
       return 200;
   }
private:
   int data[6];
   const static int array[200];
};

template<int value>
class Child : public MyClass<value>
{
public:
    int calc()
    {
        // will only work and compile for value 1,2
        return this->sizeData() + this->sizeArray();
    }
};

,

您可以使用if constexpr并立即评估constexpr lambdas

免责声明:仅C ++ 17,需要额外的括号将lambda包围起来才能进行编译,我不建议直接使用此代码。目的是仅演示

template<int value>
class MyClass
{
public:
   static int sizeData()
   {
     if constexpr(value == 1)
        return 3;
     
     if constexpr (value == 2)
        return 6;     
   }
   static int sizeArray()
   {
     if constexpr (value == 1)
        return 40;
     
     if constexpr (value == 2)
        return 200;
   }
private:
    int data[([](int v) constexpr { if (v == 1) return 3; if (v==2) return 6; }(value))];
    const static int array[([](int v) constexpr { if (v == 1) return 40; if (v==2) return 200; }(value))]; 
};

int main()
{
   MyClass<1> m1;
   MyClass<2> m2;
}
,

从C ++ 17开始,您可以使用constexpr if

template<int value>
class MyClass
{
public:
    MyClass() : data() {}

    static constexpr int sizeData() {
        if constexpr (value == 1) { return 3; }
        else if constexpr (value == 2) { return 6; }
        else { return 1; } // default value is '1'
    }
    
    static constexpr int sizeArray() {
        if constexpr (value == 1) { return 40; }
        else if constexpr (value == 2) { return 200; }
        else { return 10; } // default value is '10'
    }
private:
   int data[sizeData()];
   const static int array[sizeArray()];
};

如果使用例如C ++ 14,您可以实现自定义值特征,在编译时将给定的int值映射到另一个名为(int)的常量,并在类模板中使用这些值特征:>

template<int value>
constexpr int ValueToDataSizeMapping = 1; // default is '1'

template<>
constexpr int ValueToDataSizeMapping<1> = 3;

template<>
constexpr int ValueToDataSizeMapping<2> = 6;

template<int value>
constexpr int ValueToArraySizeMapping = 10; // default is '10'

template<>
constexpr int ValueToArraySizeMapping<1> = 40;

template<>
constexpr int ValueToArraySizeMapping<2> = 200;

template<int value>
class MyClass
{
public:
    MyClass() : data() {}
private:
   int data[ValueToDataSizeMapping<value>];
   const static int array[ValueToArraySizeMapping<value>];
};
,

不,这不能在c ++中实现。可以通过运行时变量对预编译器“ if”进行赋值。

您可以声明std::vector来解决此问题。这样,您可以使用作为参数传递的值对其进行初始化。

这时,size数组和size数据函数不需要预编译器“ if”,而只需一个简单的if-else语句。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...