1

在我使用元编程技术的一些代码中,我们使用模板化的参数,这些参数会被转发到其他地方并随后进行转换,因此我们从未真正创建其中一些类的实例。

特别是,我们使用std::vector<T>where T 没有要包含在向量中的语义。实际上,虽然我们创建了一个std::vector<shared_ptr<T> >.

代码看起来有点像这样:

class Bar : noncopyable
{ 
    // whatever
};

class Foo : public FooInterface
{
  public:
    explicit Foo( std::vector< shared_ptr<Bar> > );
};

typedef Builder1Param< FooInterface, Foo, std::vector<Bar> > FooBuilder;

通过巧妙的元编程技术,FooBuilder 知道它将传递 a vector<shared_ptr<Bar> >toFoo而不是 a vector<Bar>. 问题是因为 Bar 是不可复制的,所以它是向量的无效类型。

现在代码在我使用过的任何编译器上都可以正常编译,但我想知道它是否是有效的 C++(并且将继续在 C++11 及更高版本中如此)。

我可能应该补充一点, Bar 实际上可能是抽象的(而且经常是抽象的)。目的是表明参数是这些参数的集合(在某种意义上是 Java/C# 引用的风格)。

4

2 回答 2

1

只要你不实例化你在技术上没问题的类型,就像不完整类型一样。

然而,这是一个可怕的设计。

为了使使用更多按键来编写误导性内容而不仅仅是传递参数,所有这些扭曲成为可能。

我会重新考虑那个设计。

例如做

typedef Builder1Param< FooInterface, Foo, std::vector, Bar > FooBuilder;

对于模板定义部分,std::vector这里是模板模板参数。

于 2012-09-14T11:26:31.627 回答
0

在不符合要求std::vector<Bar>的程序中使用会产生未定义的行为。这是来自 C++11 标准中的 17.6.4.8 [res.on.functions]:Barstd::vector

在某些情况下(替换函数、处理函数、用于实例化标准库模板组件的类型的操作),C++ 标准库依赖于 C++ 程序提供的组件。如果这些组件不满足其要求,则标准对实施没有要求。

特别是,在以下情况下效果是不确定的:

...

— 对于在实例化模板组件时用作模板参数的类型,如果对该类型的操作不实现适用的要求子条款(17.6.3.5、23.2、24.2、26.2)的语义。

...

— 如果在实例化模板组件时将不完整类型 (3.9) 用作模板参数,除非该组件特别允许。

于 2012-09-14T16:00:59.883 回答