标准要求std :: tuple_size是SFINAE友好的吗? [英] Does the standard require std::tuple_size to be SFINAE-friendly?

查看:297
本文介绍了标准要求std :: tuple_size是SFINAE友好的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑附件:
问题标题是做Visual Studio编译器或Clang有不正确的行为 - 但是已经更改。

Edit append: The question title was "do Visual Studio compiler or Clang have incorrect behavior"- but that have been changed.

这里的clang和gcc编译它的方式我打算,但VS不。

So I add here that clang and gcc compiles it the way I intended, but VS does not.

我有以下代码:

template<typename S, typename T, std::size_t... I>
  void
  print_tuple_like(S& s, const T& t, std::index_sequence<I...>)
  {
    void* unused[] = { &(s << std::get<I>(t))... };      
  }

template<typename S, typename T,
         std::size_t N = std::tuple_size<decltype(T::children)>::value>
    S& operator<<(S& s, const T& t)
{
    print_tuple_like(s, t.children, std::make_index_sequence<N>{});
    return s;
}

我收到一个编译错误:

1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\utility(313): error C2338: The C++ Standard doesn't define tuple_size for this type.
1>  c:\users\jonas\documents\visual studio 2015\projects\consoleapplication7\consoleapplication7\consoleapplication7.cpp(36): note: see reference to class template instantiation 'std::tuple_size<unknown-type>' being compiled
1>  c:\users\jonas\documents\visual studio 2015\projects\consoleapplication7\consoleapplication7\consoleapplication7.cpp(43): note: see reference to function template instantiation 'void print_tuple_like<S,std::tuple<Signature::A,Signature::B>,0,1>(S &,const T &,std::integer_sequence<_Ty,0,1>)' being compiled
1>          with
1>          [
1>              S=std::ostream,
1>              T=std::tuple<Signature::A,Signature::B>,
1>              _Ty=size_t
1>          ]
1>  c:\users\jonas\documents\visual studio 2015\projects\consoleapplication7\consoleapplication7\consoleapplication7.cpp(50): note: see reference to function template instantiation 'S &operator <<<std::ostream,Signature,2>(S &,const T &)' being compiled
1>          with
1>          [
1>              S=std::ostream,
1>              T=Signature
1>          ]

这是因为visual studio中的以下代码:

That is because the following code in visual studio:

// TEMPLATE STRUCT tuple_size 
template<class _Tuple>  
struct tuple_size   {   // size of non-tuple
    static_assert(_Always_false<_Tuple>::value, "The C++ Standard doesn't define tuple_size for this type.");   
};

使替换失败成为一个硬故障 - 使SFINAE SFIAE

make the substitution failure into a hard failure- making the SFINAE SFIAE

如果我移除了

static_assert(_Always_false<_Tuple>::value, "The C++ Standard doesn't define tuple_size for this type.");

它可以工作。

纠正c ++标准规则?
或者是Microsoft错了?

Is the code strecthing the c++ standard rules? Or is Microsoft in the wrong?

推荐答案

tuple_size 是SFINAE友好,但这是由很多都是缺陷,并且在C ++ 17中已经被修正。

The standard mandates that tuple_size not be SFINAE friendly, but this is considered by many to be a defect, and looks on-track to be fixed in C++17.

需要所有的特殊化(在标准 - tuple_size 基本上是 std :: integral_constant< size_t,?> 它。 (它为编译器留下了一些自由)

It is required that all specializations (which in standard-speak for "template instantiations") of tuple_size basically be std::integral_constant<size_t, ?> or inherit from it. (It leaves some freedom to the compiler)

如果没有定义主模板,那么它不会违反。但是如果主模板被定义为一个空结构(或类似的),那么该空结构是一个模板实例(标准调用specialization),它本质上不是 std :: integral_constant< size_t,?>

If the primary template isn't defined, then it doesn't violate that. But if the primary template is defined to be an empty struct (or similar), then that empty struct is a template instance (which the standard calls a "specialization") that is not essentially std::integral_constant<size_t, ?>.

根据我的阅读,主模板(失败 code> std :: integral_constant< size_t,42> 或任何其他常数。无用和邪恶,但法律。但是作为一个空的结构违反了标准。

By my reading, it would be legal for the primary template (the "failure" case) to be std::integral_constant<size_t, 42> or any other constant. Useless and evil, but legal. But being an empty struct violates the standard.

然而,关于改变这个任务的空结构的论点是关于措辞,而不是如果这是一个好主意。

However, the arguments about changing this to mandate an empty struct are about wording, and not about if it is a good idea.

感谢@TC谁解决这个在另一个答案在这里的评论线程。

Thanks to @T.C. who solved this in a comment thread on another answer here.

这篇关于标准要求std :: tuple_size是SFINAE友好的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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