加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – MSVC无法使用模板自动参数识别constexpr函数

发布时间:2020-12-16 07:24:37 所属栏目:百科 来源:网络整理
导读:我试图为值列表中的值创建索引元查找器. 这是代码: #includetype_traits#includeutilitytemplate auto... Valuesstruct ValueTplList;template autoconstexpr int MetaFindV(int ind){ // not found case return -1;}template auto NeedleV,auto V,auto...
我试图为值列表中的值创建索引元查找器.

这是代码:

#include<type_traits>
#include<utility>

template <auto... Values>
struct ValueTplList;

template <auto>
constexpr int MetaFindV(int ind)
{   // not found case
    return -1;
}
template <auto NeedleV,auto V,auto... Vs>
constexpr int MetaFindV(int ind = 0)
{
    if constexpr (std::is_same_v<decltype(NeedleV),decltype(V)>)
    {
        return NeedleV == V ? ind : MetaFindV<NeedleV,Vs...>(ind + 1);
    }
    else
    {
        return MetaFindV<NeedleV,Vs...>(ind + 1);
    }
}
// main
template <auto,typename>
struct MetaIndexOfV;
// destructurer
template <auto V,template<auto...> class Tmpl,auto... Vs>
struct MetaIndexOfV<V,Tmpl<Vs...> >
    : std::integral_constant< int,MetaFindV<V,Vs...>() >
{};
// template variable version of it:
template <auto V,typename TemplInst>
constexpr int metaFindV_v = MetaIndexOfV<V,TemplInst>::value;

// tests
static_assert(metaFindV_v< 0,ValueTplList<0> > == 0 );
static_assert(metaFindV_v< 5,ValueTplList<0> > == -1);
static_assert(metaFindV_v< 0,ValueTplList<nullptr,0> > == 1);
static_assert(metaFindV_v< 2,ValueTplList<1,(long)2,2,3,4> > == 2);
static_assert(metaFindV_v< -1,ValueTplList<-2,-1,42> > == 1);

在这里找到行为:
https://godbolt.org/z/ukwxpN

你会发现这与gcc 7及以上版本以及clang 5及以上版本编译良好.

我想知道我是否真的通过MSVC强制要求这种仇恨的标准做错了.我现在不能自己看到它:'(

它说:

(30): error C2672: ‘MetaFindV’: no matching overloaded function found > (31): note: see reference to class template instantiation ‘MetaIndexOfV>’ being compiled
(30): error C2975: ‘V’: invalid template argument for ‘MetaFindV’,expected compile-time constant expression
(12): note: see declaration of ‘V’
(30): error C2977: ‘MetaFindV’: too many template arguments

我认为这是抱怨这条线
:std :: integral_constant< int,MetaFindV< V,Vs ...>()>
就像MetaFindV< V,Vs ...>()没有匹配功能一样.

(最后注意:如果你更改了typename的所有auto,– 稍微调整一下 – 整个事情开始起作用(但当然只对类型和类型列表而言),即使代码模式完全相同.)

解决方法

不是答案(对不起:我怀疑这是一个MSVC错误,但我不确定)但是长篇评论.

我提出了一种完全不同的方式来获得你想要的东西:

#include <type_traits>
#include <string>

template <auto... Values>
struct ValueTplList
 { };

template <auto,auto>
struct strongSame : public std::false_type
 { };

template <auto A>
struct strongSame<A,A> : public std::true_type
 { };

template <auto TargetVal,auto ... Values>
constexpr int foo (ValueTplList<Values...> const &)
{
  int ind = -1;

  (void)(    (++ind,strongSame<TargetVal,Values>::value) 
          || ... || (++ind,true) );

  return std::size_t(ind) == sizeof...(Values) ? -1 : ind;
}

template <auto V,typename TemplInst>
constexpr int metaFindV_v = foo<V>(TemplInst{});

// tests
static_assert(metaFindV_v< 0,42> > == 1);

int main ()
 {
 }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读