C++ C++;元编程;“无效”;模板参数-是否允许?

C++ C++;元编程;“无效”;模板参数-是否允许?,c++,c++11,metaprogramming,C++,C++11,Metaprogramming,在我的一些代码中,我使用了元编程技术,我们使用了模板参数,这些参数被转发到其他地方,然后被转换,所以我们从来没有实际创建过这些类的实例 特别是,我们使用std::vector,其中T没有要包含在向量中的语义。实际上,尽管我们创建了一个std::vector 代码看起来有点像这样: class Bar : noncopyable { // whatever }; class Foo : public FooInterface { public: explicit Foo(

在我的一些代码中,我使用了元编程技术,我们使用了模板参数,这些参数被转发到其他地方,然后被转换,所以我们从来没有实际创建过这些类的实例

特别是,我们使用
std::vector
,其中T没有要包含在向量中的语义。实际上,尽管我们创建了一个
std::vector

代码看起来有点像这样:

class Bar : noncopyable
{ 
    // whatever
};

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

typedef Builder1Param< FooInterface, Foo, std::vector<Bar> > FooBuilder;
类栏:不可复制
{ 
//随便
};
类Foo:公共Foo接口
{
公众:
显式Foo(std::vector);
};
typedef Builder1ParamFooBuilder;
通过巧妙的元编程技术,FooBuilder知道它将把
向量
传递给
Foo
,而不是
向量
。问题在于,因为Bar是不可复制的,所以它对于向量来说是无效的类型

现在代码在我使用过的编译器上编译得很好,但是我想知道它是否是有效的C++(并且将继续进入C++ 11和更高版本)。
我可能应该补充一点,酒吧实际上可能是抽象的(而且通常是抽象的)。其目的是指示参数是这些参数的集合(在某种意义上是Java/C#references的风格)

只要不实例化该类型,技术上就可以了,例如不完整类型

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

所有这些扭曲使得使用更多的按键来写一些误导性的东西成为可能,而不仅仅是传递参数

我会重新考虑这个设计

例如,做什么

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

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

只要您不实例化类型,您在技术上就可以了,例如不完整类型

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

所有这些扭曲使得使用更多的按键来写一些误导性的东西成为可能,而不仅仅是传递参数

我会重新考虑这个设计

例如,做什么

typedef Builder1Param< FooInterface, Foo, std::vector, Bar > FooBuilder;
typedef Builder1ParamFooBuilder;
对于模板定义部分,
std::vector
这里是一个模板模板参数。

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

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

特别是,在以下情况下,影响未定义:

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

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

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

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

特别是,在以下情况下,影响未定义:

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

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


我认为
T
上的要求都被表述为要求,以便使用涉及容器的特定表达式。例如,分配容器需要
T
CopyAssignable
,但是您可以拥有不可复制类型的容器(如果类型是可移动的,尽管不可复制,容器可能会很有用)。但是我不确定在代码> T >代码中的所有要求都是用这种方式表达的,所以我不是绝对确定的。我知道概念从来没有真正引入到C++中。主要的问题是,即使您从未尝试创建模板参数的实例,或者在常规代码中使用模板参数作为指针/引用,概念是否也会强制应用于模板参数。也就是说,假设Builder1Param是我自己的模板,因此知道如何处理它的参数。那么,如果未来的标准是在不使用任何实际需要的表达式的情况下强制执行向量元素是可复制的,这将是最奇怪的(并且打破现有的C++11代码)。除此之外,它将禁止
vector
。但这是可以复制的,我不能向你发誓,没有任何标准会在你提到
vector
时强制执行一些较弱的概念,而不是在你实际使用它来做一些事情的时候,这取决于
t
类型的属性。为了安全起见,我考虑过,为此,我应该定义自己的向量和贴图模板。我当然