bcc32:专门研究`std :: vector <bool>`

时间:2016-01-24 10:47:44

标签: c++ templates c++builder borland-c++

经典的32位Borland / Embarcadero编译器 - a.k.a.bcc32--当traits类专门用于std::vector<bool>时会出现奇怪的失败。特别是,它无法编译专业化的用法,因为它没有找到任何成员。对于其他类型 - 如std::vector<char> - 根本没有问题。使用BC ++ 5.5.1(免费)和BC ++ 7.1(RX / Seattle)进行测试。

有解决方法吗?

#include <iostream>
#include <typeinfo>
#include <vector>

template<typename T>
struct traits {  };

template<> struct traits< std::vector<char> >
{
   enum {  ENUM = 42  };

   static int func ()  {  return ENUM;  }
};

template<> struct traits< std::vector<bool> >
{
   enum {  ENUM = 666  };

   static int func ()  {  return ENUM;  }
};

///////////////////////////////////////////////////////////////////////////////////////////////////

template<typename T>
void test ()
{
   typedef traits<T> TT;

   // separate lines to see exactly where the compiler barfs
   std::cout << typeid(T).name();
   std::cout << " " << TT::ENUM;        // E2451 Undefined symbol 'ENUM'
   std::cout << " " << TT::func();      // E2451 Undefined symbol 'func'

   TT tt;
   std::cout << " " << tt.ENUM;         // E2316 'ENUM' is not a member of 'traits<std::_Bvector>'
   std::cout << " " << tt.func();       // E2316 'func' is not a member of 'traits<std::_Bvector>'
   std::cout << "\n";
}

int main ()
{
   test< std::vector<char> >();
   test< std::vector<bool> >();
   return 0;
}

注意:在某些情况下有用的 hackish workaround 是将vector<bool>的特化编码到主模板中(通常是未定义的);然后可以照常完成其他类型的特化,即使使用bcc32,代码也可以按预期工作。

运行时断言可以验证特征模板的唯一非特化化身是std::vector<bool>的化身。然后,使用这些特征的模板将在方便的位置调用断言代码(也可以是静态函数)。

template<typename T>
struct traits
{
   // specialisation for std::vector<bool> coded here...
   enum {  ENUM = 666  };

   static int func ()  {  return ENUM;  }

   static void assert_only_vector_bool_not_specialised ()
   {
      assert(typeid(T) == typeid(std::vector<bool>));
   }
};

struct traits_specialisation_base
{
   static void assert_only_vector_bool_not_specialised ()
   {
   }
};

template<> struct traits< std::vector<char> >: traits_specialisation_base
{
   enum {  ENUM = 42  };

   static int func ()  {  return ENUM;  }
};

// ...

template<typename T>
struct UsingTraits
{
   typedef traits<T> TT;

   UsingTraits ()
   {
      TT::assert_only_vector_bool_not_specialised();
   }
};

// ...

UsingTraits< std::vector<char> > erna;
UsingTraits< std::vector<bool> > fred;

1 个答案:

答案 0 :(得分:1)

function requestAjaxWebService(webServiceName, method, jsonData) { var returnData; $.ajax({ url: webServiceName, type: method, data : jsonData, dataType: "json", success: function (data) { returnData = data; }, error: function(error){ returnData = "Server error"; } }); return returnData; } std::中有些内容可疑,因此您需要使用std::vector<bool>类型。只需改为:

std::

我使用Windows表单应用程序,所以忽略表单的东西。构造函数/析构函数不是编译所必需的,但是你应该添加它们,因为 Borland BDS2006 和后面的 C ++引擎错误。有关详细信息,请参阅:

上面的代码给出了这个输出:

#include <iostream>
#include <typeinfo>
#include <vector>
//---------------------------------------------------------------------------
template<typename T> struct traits
    {
    // this is safe constructor/destructor for Borland BDS2006 and later
    traits(){};
    traits(traits& a){};
    ~traits(){};
    traits* operator = (const traits *a){};
    //traits* operator = (const traits &a){}; // use this only if you have dynamic allocation members
    };

template<> struct traits< std::vector<char> >
    {
    enum {  ENUM = 42  };
    static int func ()  {  return ENUM;  }
    };

template<> struct traits< std::_Bvector >   // here use the std type directly
    {
    enum {  ENUM = 666  };
    static int func ()  {  return ENUM;  }
    };
//---------------------------------------------------------------------------
template<typename T> void test ()
    {
    typedef traits<T> TT;

    // separate lines to see exactly where the compiler barfs
    std::cout << typeid(T).name();
    std::cout << " " << TT::ENUM;        // E2451 Undefined symbol 'ENUM'
    std::cout << " " << TT::func();      // E2451 Undefined symbol 'func'

    TT tt;

    std::cout << " " << tt.ENUM;         // E2316 'ENUM' is not a member of 'traits<std::_Bvector>'
    std::cout << " " << tt.func();       // E2316 'func' is not a member of 'traits<std::_Bvector>'
    std::cout << "\n";

    // can ignore this ... it is just output to memo I do not use console
    AnsiString s="";
    s=s+typeid(T).name() + "\n";
    s=s+" " + AnsiString( TT::ENUM ) + "\r\n";        // E2451 Undefined symbol 'ENUM'
    s=s+" " + AnsiString( TT::func() ) + "\r\n";      // E2451 Undefined symbol 'func'
    s=s+" " + AnsiString( tt.ENUM ) + "\r\n";         // E2316 'ENUM' is not a member of 'traits<std::_Bvector>'
    s=s+" " + AnsiString( tt.func() ) + "\r\n";       // E2316 'func' is not a member of 'traits<std::_Bvector>'
    Form1->mm_log->Lines->Add(s);
    }
//---------------------------------------------------------------------------
// this is your main()
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
    {
    test< std::vector<char> >();
    test< std::vector<bool> >();
    }
//---------------------------------------------------------------------------