Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 码块上的SFINAE_C++_Scope_Sfinae - Fatal编程技术网

C++ 码块上的SFINAE

C++ 码块上的SFINAE,c++,scope,sfinae,C++,Scope,Sfinae,在下面的代码中,当定义了SHOW_SFINAE_ON_TEMPLATED_ROUTINES_WORKS_AS_EXPECTED时,我们成功地演示了SFINAE ON methods的一个实例 但是,当定义了“代码”块上的TRY\u SFINAE\u时,在编译模板为“struct no\u am”时,代码块上的替换失败,编译错误将消失。然而,编译器在编译时知道,当模板为“struct no__am”时,不会执行这段代码,所以这个失败不应该是一个错误(或者我认为是这样!) 请解释为什么编译器可以在例

在下面的代码中,当定义了SHOW_SFINAE_ON_TEMPLATED_ROUTINES_WORKS_AS_EXPECTED时,我们成功地演示了SFINAE ON methods的一个实例

但是,当定义了“代码”块上的TRY\u SFINAE\u时,在编译模板为“struct no\u am”时,代码块上的替换失败,编译错误将消失。然而,编译器在编译时知道,当模板为“struct no__am”时,不会执行这段代码,所以这个失败不应该是一个错误(或者我认为是这样!)

请解释为什么编译器可以在例程上应用SFINAE,但不能在代码块上应用SFINAE。另外,如果有一种方法可以让编译器在代码块上应用SFINAE,请告诉我具体的方法

// Compiled via command:
// x86_64_6.2.0_posix_seh_rt_v5_rev1/mingw64/bin/x86_64-w64-mingw32-g++.exe -D_WIN64 -Wall -Wextra -Werror -std=c++11 -O3 -static-libgcc -static-libstdc++ sfinae_on_code_block.cc -o sfinae.exe

#define SHOW_SFINAE_ON_TEMPLATED_ROUTINES_WORKS_AS_EXPECTED
//#define TRY_SFINAE_ON_CODE_BLOCK

#include <fstream>
#include <iostream>
#include <thread>
#include <mutex>

template< typename T >
struct a_member_trait{
  static const bool exists   = false;
  static const bool is_float = false;
};

template< class T >
class see_sfinae_member_traits
{
    public:

      see_sfinae_member_traits( T t ) : the_t(t)
      {
      }

      T the_t;

#ifdef SHOW_SFINAE_ON_TEMPLATED_ROUTINES_WORKS_AS_EXPECTED
      void speak( const std::string& msg )
      {
          std::cout << msg << ":  ";
          speak_sfinae<T>();
      }

      template< class X >
      typename std::enable_if< a_member_trait<X>::exists   == true &&
                               a_member_trait<X>::is_float == true >::type
      speak_sfinae()
      {
          std::cout << "Has a_member, and that a_member is a float ["
                    << the_t.a_member
                    << "]"
                    << std::endl;
      }

      template< class X >
      typename std::enable_if< a_member_trait<X>::exists   == true &&
                               a_member_trait<X>::is_float == false >::type
      speak_sfinae()
      {
          std::cout << "Has a_member, and that a_member is NOT a float ["
                    << the_t.a_member
                    << "]"
                    << std::endl;
      }

      template< class X >
      typename std::enable_if< a_member_trait<X>::exists   == false &&
                               a_member_trait<X>::is_float == false >::type
      speak_sfinae()
      {
          std::cout << "Does NOT have a_member, float or otherwise"
                    << std::endl;
      }
#endif

#ifdef TRY_SFINAE_ON_CODE_BLOCK
      void tell( const std::string& msg )
      {
          std::cout << msg << ":  ";
          tell_all<T>();
      }

      template< class X >
      void tell_all()
      {
          std::cout << "from tell all:    ";

          if( a_member_trait<X>::exists == true && a_member_trait<X>::is_float == true )
          {
              std::cout << "Has a_member, and that a_member is a float ["
                        << the_t.a_member
                        << "]"
                        << std::endl;
          }

          if( a_member_trait<X>::exists == true && a_member_trait<X>::is_float == false )
          {
              std::cout << "Has a_member, and that a_member is NOT a float"
                        << the_t.a_member
                        << "]"
                        << std::endl;
          }

          if( a_member_trait<X>::exists == false && a_member_trait<X>::is_float == false )
          {
              std::cout << "Does NOT have a_member, float or otherwise"
                        << std::endl;
          }
      }
#endif

};

struct has_fam
{
    float a_member{ 1.1f };
};

struct has_iam
{
    int a_member{ 1 };
};

struct no_am
{
    int b_member{ 2 };
};

template<>
struct a_member_trait< has_fam >{
  static const bool exists   = true;
  static const bool is_float = true;
};

template<>
struct a_member_trait< has_iam >{
  static const bool exists   = true;
  static const bool is_float = false;
};


int main()
{
    has_fam   x_fam;
    has_iam   x_iam;
    no_am     x_noam;

    see_sfinae_member_traits< has_fam > ht_fam( x_fam );
    see_sfinae_member_traits< has_iam > ht_iam( x_iam );
    see_sfinae_member_traits< no_am   > ht_noam( x_noam );

#ifdef SHOW_SFINAE_ON_TEMPLATED_ROUTINES_WORKS_AS_EXPECTED
    ht_fam.speak( "hast_fam" );
    ht_iam.speak( "hast_iam" );
    ht_noam.speak( "not_am" );
#endif

#ifdef TRY_SFINAE_ON_CODE_BLOCK
    ht_fam.tell( "hast_fam" );
    ht_iam.tell( "hast_iam" );
    ht_noam.tell( "not_am" );
#endif

    return 0;
}
//通过命令编译:
//x86_64_6.2.0_posix_seh_rt_v5_rev1/mingw64/bin/x86_64-w64-mingw32-g++.exe-D_WIN64-Wall-Wextra-Werror-std=c++11-O3-静态libgcc-static libstdc++sfinae_on_code\u block.cc-o sfinae.exe
#按预期在模板化的例程上定义SHOW\u SFINAE\u
//#在代码块上定义TRY\u SFINAE\u
#包括
#包括
#包括
#包括
模板
构造一个成员特征{
静态常量bool exists=false;
静态常量bool为\u float=false;
};
模板
类请参见成员特征
{
公众:
参见成员特征(T):成员特征(T)
{
}
(三);
#ifdef在模板化例程上显示SFINAE,并按预期工作
void speak(const std::string和msg)
{
std::cout::type
说
{

std::我可以想象在其中起作用的一个原因是,如果代码块工作正常,您将无法获得代码的完整调试版本
,基本上删除死代码,非优化版本会用它做什么?它当然会为块创建代码。基本上这里有死代码,它与SFINAE无关:
if(false){…}
。这是什么“代码块上的SFINAE”你说的是哪一个?没有这样的东西。块中的代码必须是格式良好的,即使它没有执行。至少在你身边有一个优秀的编译器之前。希望接受@IgorTandetnik的注释作为答案(cf.)