我正在开发一个小和弦类,我想向它添加一个功能,您可以将字符串数组作为模板参数传递,以便该类可以以人类的方式打印出其当前状态- 友好的格式。 班级草图如下所示:
#include <iostream>
template <unsigned int NumBits, const char * optLabelArray[NumBits]=0> class MyBitChordClass
{
public:
MyBitChordClass() {}
static const char * GetBitLabel(unsigned int which) {return ((optLabelArray != 0)&&(which < NumBits)) ? optLabelArray[which] : "???";}
bool _bits[NumBits];
};
enum {
FRUIT_APPLE,
FRUIT_BANANA,
FRUIT_CHERRY,
NUM_FRUITS
};
const char * _fruitLabels[] = {
"Apple",
"Banana",
"Cherry"
};
int main(int, char **)
{
MyBitChordClass<NUM_FRUITS> unlabelledFruits;
MyBitChordClass<NUM_FRUITS, _fruitLabels> labelledFruits;
std::cout << labelledFruits.GetBitLabel(FRUIT_APPLE) << std::endl;
return 0;
}
如果我将
optLabelArray
模板参数的默认值更改为 nullptr
而不是 0
,这在 C++11 及更高版本下效果很好。
但是,我也想让它在 C++03 下工作,并且在 C++03 下,当我尝试编译上述程序时,我收到此错误(来自 Apple 的 clang 15.0.0):
Mac-mini:~ jaf$ g++ foo.cpp
foo.cpp:3:69: error: non-type template argument does not refer to any declaration
template <unsigned int NumBits, const char * optLabelArray[NumBits]=0> class MyBitChordClass
^
foo.cpp:28:30: note: while checking a default template argument used here
MyBitChordClass<NUM_FRUITS> unlabelledFruits;
~~~~~~~~~~~~~~~~~~~~~~~~~~^
foo.cpp:3:46: note: template parameter is declared here
template <unsigned int NumBits, const char * optLabelArray[NumBits]=0> class MyBitChordClass
^
1 error generated.
我的问题是,如何让这段代码在 C++03 下编译? 我尝试按照
here的建议对
const char *[]
进行一些显式转换,但这似乎没有帮助。
我看到这个工作的唯一方法是给默认值一个名称:
const char * null[0];
template <unsigned int NumBits, const char * optLabelArray[NumBits]=null> class MyBitChordClass
{
public:
MyBitChordClass() {}
static const char * GetBitLabel(unsigned int which) {return ((optLabelArray != null)&&(which < NumBits)) ? optLabelArray[which] : "???";}
bool _bits[NumBits];
};
您可以将
null
放在匿名命名空间中,尽管 clang 会对此发出警告(我不确定为什么)。
namespace {
const char * null[0];
}