sma*_*llB 7 c++ compiler-errors variadic-templates c++11
有这个代码:
template<class ...Args>
struct Are_Same
{
enum {value = Are_Same<Args...>::value};
};
template<class A,class... C>
struct Are_Same<A,C...>
{
enum {value = Are_Same<A,C...>::value};//HERE is THE ERROREOUS LINE
};
template<class A,class B>
struct Are_Same<A,B>
{
enum {value = std::is_same<A,B>::value};
};
Run Code Online (Sandbox Code Playgroud)
我从gcc 4.6.1收到错误:
错误:嵌套名称说明符中使用的不完整类型'Are_Same'.
我认为,通过这样做,Are_Same<A,C...>::value我将调用递归调用,最后只会扩展到Are_Same<A,B>.显然事实并非如此.谁知道我在哪里弄错了?
我认为模板的定义是错误的,在这两种情况下你都会触发精确的递归.我原以为编译器会在编译器内部出现一些stackoverflow但会产生不同的错误......
are_same可变参数模板的实现可以是:
template <class... Args> // base (optional to declare the template)
struct are_same;
template <class A, class B, class... Args> // recursion
struct are_same<A,B,Args...> {
static const bool value = is_same<A,B>::value && are_same<A,Args...>::value;
};
template <class A, class B> // stop condition
struct are_same<A,B> {
static const bool value = is_same<A,B>::value;
};
Run Code Online (Sandbox Code Playgroud)
请注意,在该recursion步骤中,将从参数列表中删除一个参数,以便要解决的新问题是原始版本的缩减版本.这种类型的模板元编程与递归非常相关,并且适用相同的规则,以便能够使用递归来确保每个递归步骤使您更接近解决方案.在这种特殊情况下,给定N个可能相同类型的列表,每个步骤减少了查找N-1类型是否相同的问题.
您也可以使用停止条件(替换前一个)作为are_same问题的退化版本:
template <class A>
struct are_same<A> {
static const bool value = true;
};
Run Code Online (Sandbox Code Playgroud)
哪个是退化的,因为询问单个类型*is_same*是否真的没有意义,但对于不同的元编程任务,它可能是合适的.
一个不同的可能更有效的算法(我不确定编译器是否会在上面的递归步骤中避免模板的实例化)不依赖于is_same:
template <class... Args>
struct are_same;
template <class A, class... Args>
struct are_same<A,A,Args...> { // recursion
static const bool value = are_same<A,Args...>::value;
};
template <class A, class B, class... Args>
struct are_same<A,B,Args...> { // cut, A and B are not the same
static const bool value = false;
};
template <class A>
struct are_same<A> { // end of recursion
static const bool value = true;
};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,编译器会喜欢recursion到cut每当两个类型相同的步骤,所以我们没有必要检查is_same内部.同时,如果编译器进入该cut步骤,我们不需要处理类型列表的其余部分,因为我们已经知道了答案.
| 归档时间: |
|
| 查看次数: |
776 次 |
| 最近记录: |