Pertanyaan C ++ "Floating Point Enum"


Saya mencari solusi menggunakan standar C ++ 03 (saya terpaksa menggunakan versi standar ini untuk beberapa tahun). Solusi untuk C ++ 11 juga diterima, tetapi tidak akan "diterima" sebagai jawaban atas pertanyaan ini.

Apa yang sederhana, cara ringkas yang saya dapat mewakili satu set terkait nilai floating point yang konstan sebagai satu jenis (mirip dengan enum) untuk memastikan jenis-keselamatan tanpa menimbulkan overhead yang signifikan dan masih memungkinkan saya untuk beroperasi pada nilai-nilai sebagai pelampung langsung ?

Hasil akhirnya adalah bahwa saya ingin dapat melakukan sesuatu seperti berikut:

enum FloatingPointEnum
{
   VALUE1 = 0.1234f,
   ...
   VALUEN = 0.6789f
};


float SomeFunction(FloatingPointEnum value)
{
    float new_value;
    /* perform some operation using "value" to calculate "new_value" */
    new_value = static_cast<float>(value); // <- a simplistic example
    return new_value;
}

Meskipun saya dapat memikirkan beberapa solusi, tidak ada yang sama bersih / sederhana / lugas seperti yang saya inginkan dan saya pikir bahwa seseorang harus sudah memiliki solusi elegan untuk masalah ini (namun saya tidak dapat menemukannya dalam pencarian saya).

EDIT: 

Saya ingin panggilan berikut ke SomeFunction dengan nilai yang tidak ditentukan secara langsung sebagai nilai dari tipe yang disebutkan tidak gagal dikompilasi:

float nonEnumeratedValue = 5.0f
SomeFunction(nonEnumeratedValue);

5
2017-10-16 16:05


asal


Jawaban:


seseorang pasti sudah memiliki solusi elegan untuk masalah ini

Ada banyak masalah yang tidak memiliki solusi elegan (dan banyak yang tidak memiliki solusi sama sekali). Apa yang membuat Anda berpikir masalah ini ada? Asumsi ini sangat salah. Yang paling dekat yang bisa Anda peroleh adalah menggunakan kelas pembungkus.

class FloatingPointEnum {
    float f;
    FloatingPointEnum(float arg) : f(arg) {}
public:
    static const FloatingPointEnum Value1;
    static const FloatingPointEnum Value2;
    operator float() const { return f; }
};
const FloatingPointEnum FloatingPointEnum::Value1(0.1234f);
const FloatingPointEnum FloatingPointEnum::Value2(0.6789f);

6
2017-10-16 16:10



Di C ++ 11 Anda dapat menggunakan constexpr untuk mencapai apa yang kamu inginkan.

constexpr - menetapkan bahwa nilai variabel atau fungsi dapat muncul dalam ekspresi konstan

http://en.cppreference.com/w/cpp/language/constexpr

Dengan constexpr Anda mendefinisikan konstanta waktu kompilasi. Ini hanya berfungsi untuk jenis literal, seperti float. Karena pada saat yang sama kita inginkan

float nonEnumeratedValue = 5.0f;
SomeFunction(nonEnumeratedValue);

gagal, kita tidak bisa menggunakan yang sederhana typedef. Sebagai gantinya kami menggunakan Boost’s BOOST_STRONG_TYPEDEF.

#include <boost/serialization/strong_typedef.hpp>

BOOST_STRONG_TYPEDEF(float, FloatingPointEnum);
constexpr float VALUE1 = 0.1234f;
constexpr float VALUEN = 0.6789f;

float SomeFunction(FloatingPointEnum value)
{
  float new_value;
  /* perform some operation using "value" to calculate "new_value" */
  new_value = static_cast<float>(value); // <- a simplistic example
  return new_value;
}

Sekarang Anda dapat memanggil fungsi hanya dengan contoh FloatingPointEnum. Sayangnya, sintaks Instansiasi tidak begitu bagus lagi

FloatingPointEnum f {VALUEN};

Sebagai alternatif, Anda cukup menggunakan bahasa pemrograman D, di mana enum titik mengambang didukung dan kode berikut berfungsi seperti yang diharapkan:

enum FloatingPointEnum
{
   VALUE1 = 0.1234f,
   //...
   VALUEN = 0.6789f
};


float SomeFunction(FloatingPointEnum value)
{
    float new_value;
    new_value = value; // No cast needed, welcome to D!
    return new_value;
}

Panggilan SomeFunction dengan float hasil dalam

Error: function test.SomeFunction (FloatingPointEnum value) is not callable using argument types (float)

1
2018-02-06 22:32