0

I want to allocate memory according to the template parameter like this:

enum typeFlag {
kFloat32 = 0,
kFloat64 = 1,
kFloat16 = 2,
kUint8 = 3,
kInt32 = 4,
kInt8  = 5,
kInt64 = 6,
kBool = 7,
kInt16 = 8
};

template<typename dtype, typename ctx>
inline TBlob<dtype,ctx>::TBlob(const size_t &size): shape_{size} {
    switch(dtype){
        case kFloat32:
            dptr_ = new float[size];
            break;
        case kFloat64:
            dptr_ = new double[size];
            break;
...

and the compiler throw an error like:

error: expected primary-expression before ‘)’ token
     switch(dtype){
                 ^

Can I achieve my goal while keeping the same meaning of dtype?

欧岳枫
  • 71
  • 5
  • Yes, but as currently written, your template parameter is a type name, not a value. Try `template` – paddy Oct 07 '20 at 07:49
  • You don't want to use it as a variable. You want to use a value template parameter instead of a type template parameter. For a variable-like parameter, you could use a reference. – IS4 Oct 07 '20 at 07:58
  • @IllidanS4 supports Monica Yes! Your description is more accurate, and I learn from your advice. Thanks a lot! – 欧岳枫 Oct 07 '20 at 08:04

2 Answers2

1

You most certainly can. I am guessing your current definition is like this

template<typename dType> ... everything else

You should change that to non-type parameter and it will work as expected. Either

template<int dType> ... rest of definition

or

template<typeFlag dType> ... rest of definition

should work depending upon your language version.

You can read about it further here.

Tanveer Badar
  • 5,438
  • 2
  • 27
  • 32
1

It seems you want to map a non-template (enumerator) parameter to a type:

#include <cstddef>

// Platform-independent type descriptions.
enum class TypeFlag {
kFloat32 = 0,
kFloat64 = 1
    // ...
};

// Platform-specific TypeFlag to type mapping.
template<TypeFlag FLAG>
struct MappedType;

// Specialize type mapping for the platform-independent
// type representations (TypeFlag) that can be represented
// on this particular platform.
template<>
struct MappedType<TypeFlag::kFloat32> { using type = float; };

template<>
struct MappedType<TypeFlag::kFloat64> { using type = double; };

// ...

template<TypeFlag FLAG>
using MappedType_t = typename MappedType<FLAG>::type;

template<TypeFlag FLAG, std::size_t SIZE>
struct TBlob {
    using BlobType = MappedType_t<FLAG>;

    TBlob() {
        dptr_ = new BlobType[SIZE];
    }

    // ...

private:
    BlobType* dptr_;
};

Note that double isn't necessarily a 64 bit float on all target architectures, so this approach is not necessarily portable, and would arguably go into a platform-specific type mapping.

dfrib
  • 70,367
  • 12
  • 127
  • 192