标准是否要求std :: tuple_size是SFINAE友好的?

时间:2015-06-24 19:40:55

标签: c++ c++14 sfinae

编辑追加: 问题标题是“做Visual Studio编译器或Clang行为不正确” - 但已经改变了。

所以我在这里补充说clang和gcc按照我的意图编译它,但是VS没有。

我有以下代码:

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中的以下代码:

// 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

如果我删除

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

它有效。

代码是否支持c ++标准规则? 或者微软是错误的?

3 个答案:

答案 0 :(得分:6)

N4140 20.4.1将jQuery(function() { var valMap = {0:'43277',00:'37943',140:'49864'};; jQuery("#lens-range").slider({ min: 0, max: valMap.length - 1, values: [0, 1], slide: function(event, ui) { $("#lensrange").val('Range: ' + valMap[ui.values[0]] + ' - ' + valMap[ui.values[1]]); //console.log($.inArray(ui.value, valMap) != -1); }, stop: function(event, ui) { lenssizeid = valMap.slice(ui.values[0], ui.values[1]+1) showproducts('','','','lens','','','',lenssizeid); //console.log(rangeArray); } }); jQuery("#lensrange").val( valMap[$("#lens-range").slider("values", 0)] + ' - ' + valMap[$("#lens-range").slider("values", 1)]); }); 的非专业版描述为:

tuple_size

通过提供定义,MSVC lib违反了标准。

然而,您应该意识到,您的问题不是涉及所涉及的编译器,而是标准库实现。

答案 1 :(得分:2)

tuple_size 的标准要求是SFINAE友好,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, ?>或从中继承。 (它为编译器留下了一些自由)

如果未定义主模板,则不会违反该模板。但是,如果主模板被定义为空结构(或类似),则该空结构是模板实例(标准称为“特化”),其实质上不是std::integral_constant<size_t, ?>

根据我的阅读,主要模板(“失败”案例)为std::integral_constant<size_t, 42>或任何其他常量是合法的。无用而邪恶,但合法。但是作为一个空结构违反了标准。

然而,关于改变它以强制要求一个空结构的论点是关于措辞,而不是关于它是否是一个好主意。

感谢@ T.C.谁在这里的另一个答案的评论帖中解决了这个问题。

答案 2 :(得分:0)

这样的事情可能会有一些修改吗?

import java.util.List