不是评估为“void ...”的非类型参数包。非法? [英] isn't non-type parameter pack that evaluates to "void..." illegal?

查看:128
本文介绍了不是评估为“void ...”的非类型参数包。非法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

gcc-4.8接受这个代码,但是不是错误,因为非类型参数包等同于 void ... 这是非法的?

  template< typename T,
typename std :: enable_if< std :: is_integral< T> :: value> type ...>
void test(T){}



我试过这个clang-3.5也接受它。这是一个编译器错误,还是我误解了某些东西?






下面是完整的测试代码, pack以简化enable_if。
这几乎与 Flaming Dangerzone的Remastered enable_if 除非替换之后,包将变为 void ...

  #include< type_traits> 

template<类型名C>
using enable_if = typename std :: enable_if< C :: value> :: type;

template< typename T,enable_if< std :: is_integral< T>> ...>
void test(T){} //#1

template<类型名T,enable_if< std :: is_floating_point< T>> ...>
void test(T){} //#2

int main()
{
test(0); // calls#1
test(0.0); // calls#2
return 0;
}

gcc-4.8编译上述代码就好了。 clang不是,因为它有一个不同的错误 http://llvm.org/bugs /show_bug.cgi?id=11723

解决方案

您提供的两个代码段都没有意义,不能有没有未展开的参数包的包扩展:
§14.5.3/ 5:


包扩展应命名一个或多个未通过嵌套包扩展扩展的参数包;这些参数包在模式中称为未展开的参数包。


回到实际问题:
如果你实际使用了一个合适的包扩展,并且使用一个非空的参数包来实例化该包扩展,则适用§14.1/ 7中的规则,因为显然非类型模板参数不能被声明为void类型。 / p>

只要不使用非空参数包实例化包扩展,就不会违反规则,因为没有参数声明 。 :)


gcc-4.8 accepts this code, but isn't it wrong since the non-type parameter pack is equivalent to void... which is illegal?

template <typename T,
          typename std::enable_if<std::is_integral<T>::value>::type...>
void test(T) {}

I tried this with clang-3.5 as well which also accepts it. Is this a compiler bug, or am I misunderstanding something?


Full test code below, which uses non-type empty parameter packs to simplify enable_if. This is almost the same as what's in Flaming Dangerzone's Remastered enable_if except after substitution the pack becomes void....

#include <type_traits>

template < typename C >
using enable_if = typename std::enable_if<C::value>::type ;

template < typename T, enable_if<std::is_integral<T>>... >
void test(T){} // #1

template < typename T, enable_if<std::is_floating_point<T>>... >
void test(T){} //#2

int main()
{
   test(0);   // calls #1
   test(0.0); // calls #2
   return 0;
}

gcc-4.8 compiles the above code just fine. clang doesn't but that's because it has a different bug http://llvm.org/bugs/show_bug.cgi?id=11723.

解决方案

Both code snippets you provided are not making sense, since you can't have a pack expansion without an unexpanded parameter pack: §14.5.3/5:

The pattern of a pack expansion shall name one or more parameter packs that are not expanded by a nested pack expansion; such parameter packs are called unexpanded parameter packs in the pattern.

Back to the actual problem: If you actually used a proper pack expansion and you instantiated that pack expansion with a non-empty parameter pack, the rule in §14.1/7 applies, because obviously a non-type template parameter cannot be declared to have void type.

As long as that pack expansion is not instantiated with a non-empty parameter pack, no rule is violated, since no parameter-declaration is done. :)

这篇关于不是评估为“void ...”的非类型参数包。非法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆