Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to make a template function to apply on an array of any length in C++?

I have a situation where I need to read a text file and to check whether a mnemonic is valid, so I have a dynamic set of mnemonics (for now 1226!) which I can alter later when necessary. So I first tried this way:

enum InstrID
{
    I_INVALID = 0,

    I_AAA,
    I_AAD,
    ...
};

static char const * nameOfinstrID[] =
{
    "???",

    "AAA",
    "AAD",
    ...
};


struct InstrIDIterator
{
    template< int N > static InstrIDIterator Make(char const * begin[N], size_t index = N)
    {
        InstrIDIterator result;
        result.index = index;
        result.begin = begin;
        return result;
    }

    std::map< std::string, InstrID >::value_type operator * () { return std::map< std::string, InstrID >::value_type(begin[index], InstrID(index)); }

    ... // iterator-like stuff

    size_t index;
    char const ** begin;
};

InstrID getInstrID(std::string const & name)
{
    static std::map< std::string, InstrID > instrID_map(InstrIDIterator::Make(nameOfinstrID, 0), InstrIDIterator::Make(nameOfinstrID));

    return instrID_map[name];
}

...

But I got this error under MSVC 2013:

error C2784: 'x86_text_grammar::InstrIDIterator x86_text_grammar::InstrIDIterator::Make(const char *[N],size_t)' : could not deduce template argument for 'const char *[N]' from 'const char *[1225]'

So my question is: is it an issue only regarding MSVC 2013? or is it something normal even for ISO C++x11?

Of course, in this case I can proceed with a less generic way which compiles fine (and better for checking the string array dimension) :

enum InstrID
{
    I_INVALID = 0,

    I_AAA,
    I_AAD,
    ...
    InstrID_max
};

static char const * nameOfinstrID[InstrID_max] =
{
    "???",

    "AAA",
    "AAD",
    ...
};

struct InstrIDIterator
{
    static InstrIDIterator Make(char const * begin[InstrID_max], size_t index = InstrID_max)
    {
        InstrIDIterator result;
        result.index = index;
        result.begin = begin;
        return result;
    }

    ...
};
like image 338
hlide Avatar asked Dec 30 '25 08:12

hlide


1 Answers

A function parameter of form T[N] is adjusted (that is to say, it is effectively exactly the same as) T*. So the parameter char const * begin[InstrID_max] is the same as char const** begin.

You can use a reference to an array of a a certain size as parameter with the syntaxT (&array_name)[ARRAY_LENGTH]. That leaves you with

template<size_t N>
static InstrIDIterator Make(const char* (&begin)[N],  size_t index = N);
like image 174
juanchopanza Avatar answered Dec 31 '25 23:12

juanchopanza