SFINAE Constructors [duplicate]
Asked Answered
R

2

6

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) {
}
Resistencia answered 11/7, 2018 at 19:4 Comment(0)
A
12

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.

Agnola answered 11/7, 2018 at 19:14 Comment(1)
I can't say I understand why the value-based thing gets SFINAE done while the typename-based one doesn't... Could you please explain it a little bit more? So can it be said that the value-based SFINAE is "stronger" than the typename-based?Laura
I
1

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.

Impenetrable answered 11/7, 2018 at 19:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.