【发布时间】:2012-10-23 17:08:53
【问题描述】:
我有一个关于可变参数模板的问题。我有一个类以下列方式使用它们:
template <class... T>
struct A {
A(B& arg); // (1)
A(typename T::B& args...); // (2)
};
typename T::B 是某种类型,预期对于参数包中的所有实例都相等。为了便于演示,我将这种类型称为B。该类包含参数包中每个参数的B 实例。第二个构造函数(2) 初始化这些成员。为方便起见,有一个构造函数(1),它只接受一个实例并用相同的实例初始化所有成员。
构造函数的定义对我的问题并不重要,你可以将它们留空。下面提供了一个更完整的示例。
现在的问题是,如果你只用一个参数初始化 A,构造函数就会发生冲突。 g++-4.7 在这里有点糊涂,然后跳了出来,但是仔细看课程后,问题就很明显了。
问题:
标准对这种情况有什么看法?这是应该/可以由编译器解决的歧义还是我应该避免这种情况?
避免它的最佳策略是什么?根本没有指定第一个构造函数之类的东西吗?我也可以将第一个构造函数的功能放在静态方法中,但这会使 API 更加不均匀。
感谢您的回答!
完整示例:
struct B {};
struct C
{
using B = ::B;
};
template <class... T>
struct A
{
A(B& arg) {}
A(typename T::B & ... args) {}
};
int main()
{
A<C> x(B()); // Edit: Should be: A<C> X{B()}; But not related to the problem.
return 0;
}
【问题讨论】:
-
@KerrekSB 如果椭圆在逗号之后就像它是一个参数一样,它只会是一个可变参数函数,比如
A(typename T::B& args, ...); -
@SethCarnegie:哦,对不起,我看错了代码。没关系。
-
@Markus 好吧,当你
A<B> x { B() }时,你想叫哪一个? -
@SethCarnegie 实际上,在这种情况下我不会在意,因为两个构造函数都做同样的事情。如果调用更专业的构造函数,即
(1),它会感觉更自然。但我认为最好的情况是编译器失败(比g++现在更优雅)。
标签: c++ c++11 variadic-templates ambiguous