我想阻止班上的客户做些蠢事。为此,我使用了类型系统,并使我的类只接受特定类型作为输入。考虑下面的例子(不是真正的代码,为了举例我没有像虚拟析构函数这样的东西):
class MyDataChunk
{
//Look Ma! Implementation!
};
class Sink;
class Source
{
virtual void Run() = 0;
Sink *next_;
void SetNext(Sink *next)
{
next_ = next;
}
};
class Sink
{
virtual void GiveMeAChunk(const MyDataChunk& data)
{
//Impl
};
};
class In
{
virtual void Run
{
//Impl
}
};
class Out
{
};
//Note how filter and sorter have the same declaration. Concrete classes
//will inherit from them. The seperate names are there to ensure only
//that some idiot doesn't go in and put in a filter where someone expects
//a sorter, etc.
class Filter : public Source, public Sink
{
//Drop objects from the chain-of-command pattern that don't match a particular
//criterion.
};
class Sorter : public Source, public Sink
{
//Sorts inputs to outputs. There are different sorters because someone might
//want to sort by filename, size, date, etc...
};
class MyClass
{
In i;
Out o;
Filter f;
Sorter s;
public:
//Functions to set i, o, f, and s
void Execute()
{
i.SetNext(f);
f.SetNext(s);
s.SetNext(o);
i.Run();
}
};
我不想要的是有人稍后回来然后去,“嘿,看!分拣机和过滤器具有相同的签名。我可以制作一个同时执行这两者的通用!”,从而打破了语义差异{ {1}}需要。
这是一种常见的要求,如果是这样,我该如何为它实施测试?
答案 0 :(得分:3)
一般来说,没有。如果语句没有编译(即无效ISO C ++),则编译器不再有义务创建可执行文件。
有一个着名的例外,甚至有一个缩写:SFINAE,或替换失败不是错误。粗略地说,在许多情况下(例如重载解析),编译器将隐式地实例化一些模板,以考虑结果。如果编译器尝试无法编译的实例化,然后停止整个编译过程,那将是非常烦人的。因此,在这种情况下,它会默默地丢弃实例化错误。
可以利用此SFINAE机制在编译时确定某些属性。考虑一下:
template<typename T> class Foo() {
static char test(T);
static int test(...);
static const size_t result = sizeof(test(0));
};
现在,如果表达式T(0)
编译,即如果0可以转换为T,则Foo :: result是sizeof(char)== 1,否则Foo :: result是sizeof(int)。
答案 1 :(得分:2)
为什么要等到运行时?编译时间检查(例如static asserts)可以让违规代码无法编译。
但是要回答你的问题,我相信不 - 你不能这样做,除非你在测试中运行编译器。
但是,请再次查看编译时断言或concept checks。没有理由等到测试时间才能看到这些错误。
答案 2 :(得分:1)
最新澄清问题很简单:
void foo(Filter*);
void foo(Sorter*);
template<typename T> void test() {
foo((T*)NULL);
}
如果有人通过了同时使用Filter和Sorter的类,则重载决策是不明确的。
答案 3 :(得分:0)
要测试预期的编译时失败,您需要在自动构建的某种框架中运行测试。框架调用编译器从源代码构建,检查编译返回代码是否符合预期成功/失败,然后运行生成的测试.exe(如果是运行时测试)。
我知道Boost的回归测试中存在这样的特征,尽管我实际上还没有研究过它的实现方式。也许你可以看看那些例子/想法。