0

I am using an external library to write binary data from a data store object that is constructed from a template. This is a general question so I won't mention the library here. The templates are explicitly instantiated so they can only be of either float or double types. I wrap the call to the library writer in my own method which needs to decide what precision to request from the library writer. This, of course, depends on which version of the class that is in use. I can't use a conditional like this:

typedef std::conditional<std::is_same<T, float>::value, MACRO_FLOAT_TYPE, MACRO_DOUBLE_TYPE>::type T1;

because I don't want to define a type I just want to define the value of precisionType in the example below:

template <typename T>
class Data
{
    // My class which can either contain data as float or double precision

    // My wrapper for the library writing method which takes a custom typedef
    void writeData(customType precisionType);
}

int main()
{
    // Assume I need two different versions of the data store
    Data<float> * dFloat = new Data<float>();
    Data<double> * dDouble = new Data<double>();

    // I have to call
    dFloat->writeData(MACRO_TYPE_FLOAT);
    dDouble->writeData(MACRO_TYPE_DOUBLE);
}

But, I want to hide this macro argument from the user as it depends on the library being used and could be different in the future.

I would like to make precisionType a private constant member of the class that is chosen at compile-time when the templates are expanded. The user can then just call ->writeData() and not worry about the precision type argument. How can I achieve this?

CodingLumis
  • 594
  • 2
  • 22
  • Can't you just add a overload to `Data` that takes no parameters and depending on the template type call `writeData` that takes a parameter with the correct parameter? – NathanOliver Jul 27 '17 at 14:33
  • @NathanOliver I'm not sure I understand your suggestion. You mean an overloaded constructor? – CodingLumis Jul 27 '17 at 14:45
  • No, overload `writeData` to take nothing and then in there overload you call `writeData(MACRO_TYPE_FLOAT)` or `writeData(MACRO_TYPE_DOUBLE)` depending on the template type. – NathanOliver Jul 27 '17 at 14:46
  • @NathanOliver OK, right, so how do I perform the `if` on `T` to ensure the correct one is used? – CodingLumis Jul 27 '17 at 14:50

2 Answers2

1

Having come across this answer and with some prompts from @NathanOliver, I realised that the std::is_same() can be used to solve the problem. Create a private const member of customType in the Data class and assign through an initialiser list then just use it inside writeData() without having to use an argument at all.

template <typename T>
class Data
{
    // My class which can either contain data as float or double precision

    const customType dataType;

    Data() : dataType(std::is_same<T, float>::value ? MACRO_TYPE_FLOAT : MACRO_TYPE_DOUBLE) {};

    // My wrapper for the library writing method
    void writeData() { // uses dataType internally };
}

int main()
{
    // Assume I need two different versions of the data store
    Data<float> * dFloat = new Data<float>();
    Data<double> * dDouble = new Data<double>();

    // I have to call
    dFloat->writeData();
    dDouble->writeData();
}
CodingLumis
  • 594
  • 2
  • 22
  • Just about what I was going to make. I was going to do it from the function side but this works just as well. – NathanOliver Jul 27 '17 at 15:11
  • Another option could be to use a second template argument as `template class Data { writeData(customType U); }` and then edit the explicit instantiations to take the correct macro. – CodingLumis Jul 28 '17 at 13:28
0

Perhaps I'm misunderstanding your question and maybe it's been too long since I've written any C++, but why can't you just use T in your method signature for your class declaration?

template <typename T>
class Data
{
    writeData(T precisionType);
}

Then instantiating it as Data<float> * dFloat = new Data<float>(); will force dFloat->writeData(floatVal); to only accept variables of type float.

fetherolfjd
  • 276
  • 1
  • 11
  • `writeData` needs to take type `customType` as that is what the library method requires so I can't pass a native type. My issue is how to ensure the correct macro is chosen which expands to a value of type `customType`. – CodingLumis Jul 27 '17 at 14:42
  • Ah, gotcha. Completely disregard my answer then. :) – fetherolfjd Jul 27 '17 at 15:15