在默认模板参数中调用constexpr [英] Calling constexpr in default template argument

查看:142
本文介绍了在默认模板参数中调用constexpr的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++ 11中,我使用constexpr函数作为模板参数的默认值 - 它如下所示:

  template< int value> 
struct bar
{
static constexpr int get()
{
return value;
}
};

template< typename A,int value = A :: get()>
struct foo
{
};

int main()
{
typedef foo< bar< 0>类型;

return 0;
}

G ++ 4.5和4.7编译这个,但Clang ++ 3.1没有。 clang的错误消息是:

  clang_test.cpp:10:3​​5:error:非类型模板参数不是常量expression 
template< typename A,int value = A :: get()>
^ ~~~~~~~
clang_test.cpp:17:19:注意:同时检查这里使用的默认模板参数
typedef foo< bar< 3>类型;
~~~~~~~~~ ^〜
clang_test.cpp:10:3​​5:注意:undefined函数'get'不能用于常量表达式
template< typename A ,int value = A :: get()>
^
clang_test.cpp:4:23:注意:在这里声明
static constexpr int get()
^
1错误生成。

哪一个正确?


<在LLVM IRC频道的理查德·史密斯(zygoloid)与我谈了这个问题,这是你的回答




















$ b

 < litb> hello folks 
< litb> zygoloid,在这种情况下应该发生什么?
< litb> http://stackoverflow.com/questions/10721130/calling-constexpr-in-default-template-argument
< litb>它似乎是ang的行为是令人惊讶的
< litb> zygoloid,我不能应用实例化点规则到constexpr
功能模板。如果我调用这样的函数模板,调用定义的
POI经常是* after *专门化引用,这意味着在
的点调用,constexpr函数模板专门化是未定义的。
< zygoloid>这是一个可怕的混乱。 Clang不做标准的意图,但
你注意到,实际规格是光荣地不清楚
< d0k> (
< zygoloid>我们应该实例化bar< 3> :: get(),因为它是odr使用,但是我们
不,因为我们不正确地相信它在未评估的上下文中使用
< zygoloid>相反,实例化点太晚了:/
< zygoloid> PR11851

所以看来有时,Clang实例化称为函数模板或类模板的成员函数,但它们的实例化对于调用来说太晚了,在其他情况下,它甚至不实例化它们,因为它认为它永远不会需要它们(未评估的上下文)。


In C++11 I am using a constexpr function as a default value for a template parameter - it looks like this:

template <int value>
struct bar
{
    static constexpr int get()
    {
        return value;
    }
};

template <typename A, int value = A::get()>
struct foo
{
};

int main()
{
    typedef foo<bar<0>> type;

    return 0;
}

G++ 4.5 and 4.7 compiles this, but Clang++ 3.1 does not. The error message from clang is:

clang_test.cpp:10:35: error: non-type template argument is not a constant expression
template <typename A, int value = A::get()>
                                  ^~~~~~~~
clang_test.cpp:17:19: note: while checking a default template argument used here
        typedef foo<bar<3>> type;
                ~~~~~~~~~^~
clang_test.cpp:10:35: note: undefined function 'get' cannot be used in a constant expression
template <typename A, int value = A::get()>
                                  ^
clang_test.cpp:4:23: note: declared here
        static constexpr int get()
                             ^
1 error generated.

Which one is correct?

解决方案

Richard Smith (zygoloid) at the LLVM IRC channel had a short talk with me about this issue which is your answer

<litb> hello folks
<litb> zygoloid, what should happen in this case?
<litb> http://stackoverflow.com/questions/10721130/calling-constexpr-in-default-template-argument
<litb> it seems to be clang's behavior is surprising
<litb> zygoloid, i cannot apply the "point of instantiation" rule to constexpr 
  function templates. if i call such a function template, the called definition's 
  POI often is *after* the specialization reference, which means at the point of 
  the call, the constexpr function template specialization is "undefined".
<zygoloid> it's a horrible mess. Clang does not do what the standard intends, but 
  as you note, the actual spec is gloriously unclear
<d0k> :(
<zygoloid> we should instantiate bar<3>::get(), because it is odr-used, but we 
  don't, because we incorrectly believe it's used in an unevaluated context
<zygoloid> conversely, the point of instantiation is too late :/
<zygoloid> PR11851

So it seems that sometimes, Clang instantiates called function templates or member function of class templates but their instantiation is too late for the call to see, and at other cases it doesn't even instantiate them because it thinks it will never need them (unevaluated context).

这篇关于在默认模板参数中调用constexpr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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