Using std :: enable_if with anonymous type parameters

I am trying to use std::enable_ifwith an unused and unnamed type parameter so as not to distort the type return. However, the following code does not compile.

#include <iostream>

template <typename T, typename = std::enable_if_t<!std::is_integral<T>::value>>
T foo() { std::cout << "non-integral" << std::endl; return T(); }

template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
T foo() { std::cout << "integral" << std::endl; return T(); }

int main() {
  foo<float>();
  foo<int>();
}

The compiler says:

7:3: error: redefinition of 'template<class T, class> T foo()'
4:3: note: 'template<class T, class> T foo()' previously declared here
 In function 'int main()':
11:12: error: no matching function for call to 'foo()'
11:12: note: candidate is:
4:3: note: template<class T, class> T foo()
4:3: note: template argument deduction/substitution failed:

What is the problem? How do I change the code to compile it? The Discovery of Modern C ++ text edition explicitly encourages the use of std::enable_ifanonymous type parameters.

EDIT: , , std::enable_if . , , , . , , , .

+6
4

, , , .

, .

:

template<typename = int>
void f() {}

template<typename = void>
void f() {}

int main() {
    f<>();
}

, , f .

, foo foo<void, void>, .
, , , , .

- , .


, std::enable_if_t .
:

#include <type_traits>
#include <iostream>

template <typename T, std::enable_if_t<!std::is_integral<T>::value>* = nullptr>
T foo() { std::cout << "non-integral" << std::endl; return T(); }

template <typename T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
T foo() { std::cout << "integral" << std::endl; return T(); }

int main() {
    foo<float>();
    foo<int>();
}

, () OP , , @T.C. .
, :

; . - . : .

+6

enable_if :

template <typename T>
std::enable_if_t<!std::is_integral<T>::value,T>
foo() { std::cout << "non-integral" << std::endl; return T(); }

template <typename T>
std::enable_if_t<std::is_integral<T>::value, T>
foo() { std::cout << "integral" << std::endl; return T(); }

, enable_if_t ++ 14, typename std::enable_if<std::is_integral<T>::value, T>::type. .

( ) :

template <typename T>
T foo_impl(std::false_type) { std::cout << "non-integral" << std::endl; return T(); }

template <typename T>
T foo_impl(std::true_type) { std::cout << "integral" << std::endl; return T(); }

template <typename T>
T foo(){
    return foo_impl<T>(typename std::is_integral<T>::type{});
}
+3

, SFINAE. / .

template <typename T>
auto foo() -> std::enable_if_t<!std::is_integral<T>::value, T>
{ std::cout << "non-integral" << std::endl; return T(); }

template <typename T>
auto foo() -> std::enable_if_t<std::is_integral<T>::value, T>
{ std::cout << "integral" << std::endl; return T(); }
+2

, enable_if_t .

#include <iostream>
#include <type_traits>

template <typename T, std::enable_if_t<!std::is_integral<T>::value, int> = 0>
T foo() { std::cout << "non-integral" << std::endl; return T(); }

template <typename T, std::enable_if_t<std::is_integral<T>::value, int> = 0>
T foo() { std::cout << "integral" << std::endl; return T(); }

int main() {
  foo<float>();
  foo<int>();
}

++ 14.

++ 11 ( ++ 11) enable_if_t.

#include <iostream>
#include <type_traits>

template <typename T,
          typename std::enable_if<!std::is_integral<T>::value, int>::type = 0>
T foo() { std::cout << "non-integral" << std::endl; return T(); }

template <typename T,
          typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
T foo() { std::cout << "integral" << std::endl; return T(); }

int main() {
  foo<float>();
  foo<int>();
}
+2

Source: https://habr.com/ru/post/1658871/


All Articles