Errors using decltype () and SFINAE methods

In response to .. some other question somewhere, I wrote this code.

struct no_type{};
template<typename T> struct has_apply {
    static decltype(T().apply<0u>(double())) func( T* ptr );
    static no_type func( ... );
    static const bool result = !std::is_same<no_type, decltype(func(nullptr))>::value;
};

class A {
public:
    template< unsigned n >
    void apply( const double& );

};
class B {
};

int main()
{
  std::cout << std::boolalpha << has_apply< A >::result << '\n';
  std::cout << std::boolalpha << has_apply< B >::result << '\n';
  std::cin.get();
  return( 0 );
}

Now it seems to me that the result should be true if T offers a non-stationary member function "apply", which takes the double value rvalue and the literal of the template parameter, and false otherwise. However, the above example does not actually compile for class B at compilation has_apply<B>. Shouldn't the fact that replacing T in decltype does not mean that it simply calls another function? Isn't that the thing that relates to SFINAE?

Decided in the funniest, most senseless way:

struct no_type{};
template<typename T> struct has_apply {
    template<typename U> static decltype(U().apply<0u>(double())) func( U* );
    template<typename U> static no_type func( ... );
    static const bool result = !std::is_same<no_type, decltype(func<T>(nullptr))>::value;
};

class A {
public:
    template< unsigned n >
    void apply( const double& );

};
class B {
};

int main()
{
  std::cout << std::boolalpha << has_apply< A >::result << '\n';
  std::cout << std::boolalpha << has_apply< B >::result << '\n';
  std::cin.get();
  return( 0 );
}
+3
source share
2

SFINAE , , , ( ) , .

, decltype(T().apply<0u>(double())) decltype(T().template apply<0u>(double())), T() . : T().apply<0u>, T, apply < .? apply -, < . OTOH apply (, ), < "". , . , , , apply: . .template ( ->template ::template): , , , , , shouldn ' t - .

, , , g++ 4.5.0 -std=c++0x:

#include <iostream>

template < class T >
decltype( T().template apply< 0u >( double() ) ) f( T &t )
{
    return t.template apply< 0u >( 5. );
}

const char *f( ... )
{
    return "no apply<>";
}

class A {
public:
    template < unsigned >
    int apply( double d )
    {
        return d + 10.;
    }
};

class B {};

int main()
{
    A a;
    std::cout << f( a ) << std::endl;
    B b;
    std::cout << f( b ) << std::endl;
}

:

15
no apply<>

, .template f(), :

no apply<>
no apply<>

class A, apply. SFINAE !

+3

, , , .

, declval(), . T()

 decltype( *(T*)0->template apply< 0u >( double() ) ) )

, decltype .

T T_obj( void );

decltype( T_obj().template apply< 0u >( double() ) ) )

, Stroustrup , . ++ ?

++ 0x , . - " " ++, , ?

0

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


All Articles