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

c – 专门化模板类构造函数

发布时间:2020-12-16 09:56:01 所属栏目:百科 来源:网络整理
导读:我想专门化一个模板类构造函数: 如果type为int,则默认值为50和-50.如果它的浮动默认值应为0.5和-0.5. 我的代码是: #include iostream#include limits#include type_traitstemplatetypename Tclass Foo{public: templatetypename = typename std::enable_if
我想专门化一个模板类构造函数:

如果type为int,则默认值为50和-50.如果它的浮动默认值应为0.5和-0.5.

我的代码是:

#include <iostream>
#include <limits>
#include <type_traits>

template<typename T>
class Foo{
public:
    template<typename = typename std::enable_if<
        std::is_integral<T>::value&& !std::is_floating_point<T>::value>::type>
        Foo(T value1 = 50,T value2 = -50) :value1_(value1),value2_(value2){}

    template<typename = typename std::enable_if<
        std::is_floating_point<T>::value>::type>
        Foo(T value1 = 0.5,T value2 = -0.5,void* dummy = 0) : value1_(value1),value2_(value2){}
    T value1_,value2_;
};

int main()
{
    Foo<float> test;
    std::cout << test.value1_ << " " << test.value2_ << 'n';

    Foo<int> test2;
    std::cout << test2.value1_ << " " << test2.value2_;
}

它在视觉工作室2013年works just fine.

但是gcc 4.9.2 rejects it:

main.cpp: In instantiation of 'class Foo<float>':
main.cpp:29:13:   required from here
main.cpp:19:3: error: no type named 'type' in 'struct std::enable_if<false,void>'
   Foo(T value1 = 50,value2_(value2){}
   ^
main.cpp: In instantiation of 'class Foo<int>':
main.cpp:32:11:   required from here
main.cpp:23:3: error: no type named 'type' in 'struct std::enable_if<false,void>'
   Foo(T value1 = 0.5,value2_(value2){}
   ^

我的代码错了吗?如果是这样,为什么visual studio会编译它?或者它可能是一个gcc bug?!

解决方法

您的代码不正确.顶级T不能在SFINAE上下文中用于其方法,这正是您要尝试的方法.只有在直接上下文中发生的替换才可能导致扣减失败(§14.8.2/ 8):

Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure. [ Note: The evaluation of the substituted types and expressions can result in side effects such as the instantiation of class template specializations and/or function template specializations,the generation of implicitly-defined functions,etc. Such side effects are not in the “immediate context” and can result in the program being ill-formed. — end note ]

GCC和Clang拒绝你的代码是正确的.

解决方法是引入默认为顶级T的虚拟模板类型,以及该模板上的SFINAE.像这样:

template <typename T_ = T,// now the subsequent line *is* in
                           // an immediate context
          typename = typename std::enable_if <
              std::is_integral<T_>::value&& !std::is_floating_point<T_>::value
          >::type>
Foo(T value1 = 50,T value2 = -50) 
:value1_(value1),value2_(value2) { }

请注意,is_integral和is_floating_point是互斥的,您只需要检查一个或另一个.

在这个例子中,将默认值分配给另一个结构可能要简单得多,这样你就可以只有一个构造函数,如下所示:

Foo(T value1 = FooDefaults<T>::value1,T value2 = FooDefaults<T>::value2)
: value1_(value1),value2_(value2)
{ }

(编辑:李大同)

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

    推荐文章
      热点阅读