specialize a template class constructor

China☆狼群 提交于 2019-12-05 21:33:23

Your code is incorrect. The top-level T cannot be used in a SFINAE context for its methods, which is what you are trying to do. Only a substitution that takes place in an immediate context may result in a deduction failure (§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 and Clang are correct in rejecting your code.

A workaround is just to introduce a dummy template type that defaults to the top-level T, and SFINAE on that one. Like so:

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) { }

Note that is_integral and is_floating_point are mutually exclusive, you should only have to check one or the other.

In this example, it'd probably be a lot simpler just to farm out the default values to another struct, so that you can have just one constructor that looks like:

Foo(T value1 = FooDefaults<T>::value1, T value2 = FooDefaults<T>::value2)
: value1_(value1), value2_(value2)
{ }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!