SFINAE Constructors [duplicate]

元气小坏坏 提交于 2019-12-04 03:48:23

问题


I have been liking SFINAE syntax like this for functions, seems to generally work well!

template <class Integer, class = typename std::enable_if<std::is_integral<Integer>::value>::type>
T(Integer n) {
    // ...
}

But am running into an issue when I want to do this as well in the same class...

template <class Float, class = typename std::enable_if<std::is_floating_point<Float>::value>::type>
T(Float n) {
    // ...
}

Getting errors such as this:

./../T.h:286:2: error: constructor cannot be redeclared
        T(Float n) {
        ^
./../T.h:281:2: note: previous definition is here
        T(Integer n) {
        ^
1 error generated.

Shouldn't these constructors only exist for the appropriate types and never at the same time? Why do they conflict?

Am I being a bit thick here?

This on the other hand does work (but I don't like the syntax as much):

template <class Integer>
T(Integer n, typename std::enable_if<std::is_integral<Integer>::value>::type* = nullptr) {
}

template <class Float>
T(Float n, typename std::enable_if<std::is_floating_point<Float>::value>::type* = nullptr) {
}

回答1:


Use a non-type template parameter instead:

template <class Integer,
    std::enable_if_t<std::is_integral<Integer>::value, int> = 0>
T(Integer n) {
    // ...
}

template <class Float,
    std::enable_if_t<std::is_floating_point<Float>::value, int> = 0>
T(Float n) {
    // ...
}

This works because the compiler has to substitute the first template parameter before it can determine the type of the value parameter.




回答2:


One way to fix this is to add extra , typename=void arguments so that none of the overloads has the same number of template parameters.



来源:https://stackoverflow.com/questions/51292574/sfinae-constructors

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!