有什么方法可以使模板函数应用于 C++ 中任意长度的数组?
Is there any way to make a template function to apply on an array of any length in C++?
我有一种情况需要读取文本文件并检查助记符是否有效,所以我有一组动态助记符(目前为 1226!),我可以在以后必要时更改。所以我首先尝试这样:
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];
}
...
但是我在 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]'
所以我的问题是:它是否仅与 MSVC 2013 相关?还是即使对于 ISO C++x11 也是正常的?
当然,在这种情况下,我可以继续使用一种不太通用的方式,它可以很好地编译(并且更好地检查字符串数组维度):
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;
}
...
};
调整了T[N]
形式的函数参数(也就是说,它实际上与T*
完全相同)。所以参数char const * begin[InstrID_max]
和char const** begin
是一样的。
您可以使用对特定大小数组的引用作为参数,语法为T (&array_name)[ARRAY_LENGTH]
。这让你
template<size_t N>
static InstrIDIterator Make(const char* (&begin)[N], size_t index = N);
我有一种情况需要读取文本文件并检查助记符是否有效,所以我有一组动态助记符(目前为 1226!),我可以在以后必要时更改。所以我首先尝试这样:
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];
}
...
但是我在 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]'
所以我的问题是:它是否仅与 MSVC 2013 相关?还是即使对于 ISO C++x11 也是正常的?
当然,在这种情况下,我可以继续使用一种不太通用的方式,它可以很好地编译(并且更好地检查字符串数组维度):
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;
}
...
};
调整了T[N]
形式的函数参数(也就是说,它实际上与T*
完全相同)。所以参数char const * begin[InstrID_max]
和char const** begin
是一样的。
您可以使用对特定大小数组的引用作为参数,语法为T (&array_name)[ARRAY_LENGTH]
。这让你
template<size_t N>
static InstrIDIterator Make(const char* (&begin)[N], size_t index = N);