C++ اثنين أو أكثر من أنواع البيانات في الإعلان

StackOverflow https://stackoverflow.com/questions/231868

  •  04-07-2019
  •  | 
  •  

سؤال

أنا على خطأ غريب من g++ 3.3 في التعليمات البرمجية التالية:

#include <bitset>
#include <string>

using namespace std;

template <int N, int M>
bitset<N> slice_bitset(const bitset<M> &original, size_t start) {
    string str = original.to_string<char, char_traits<char>, allocator<char> >();
    string newstr = str.substr(start, N);
    return bitset<N>(newstr);
}

int main() {
    bitset<128> test;
    bitset<12> result = slice_bitset<12, 128>(test, 0);
    return 0;
}

الخطأ هو كما يلي:

In function `std::bitset slice_bitset(const std::bitset&, unsigned int)':
syntax error before `,' token
`char_traits' specified as declarator-id
two or more data types in declaration of `char_traits'
`allocator' specified as declarator-id
two or more data types in declaration of `allocator'
syntax error before `>' token

يجب أن يكون شيئا سخيفا حقا, ولكن قلت أن بلدي بطة مطاطية صديق دون جدوى.

شكرا Lazyweb.

هل كانت مفيدة؟

المحلول

اختيار إجابة من CAdaker فوق يحل المشكلة ، ولكن لا يفسر لماذا فإنه لا يحل المشكلة.

عندما وظيفة قالب يتم تحليل البحث لا يأخذ مكان في تعتمد على أنواع.ونتيجة لذلك ، يبني مثل التالية يمكن تحليل:

template <typename T>
class B;

template <typename T>
void foo (B<T> & b) {
  // Use 'b' here, even though 'B' not defined
}

template <typename T>
class B
{
  // Define 'B' here.
};

ومع ذلك ، فإن هذه "الميزة" تكلفة و في هذه الحالة هو أن تعريف 'فو' يتطلب تلميحات على محتويات القالب 'ب'.إذا 'فو' يستخدم متداخلة نوع 'ب' ، ثم typename الكلمات الرئيسية المطلوب أن نخبر المترجم أن اسم نوع:

template <typename T>
void foo (B<T> & b)
{
  typename B<T>::X t1;    // 'X' is a type - this declares t1
  B<T>::Y * t1;           // 'Y' is an object - this is multiplication
}

دون 'typename' في أعلاه المترجم سوف نفترض أن X هو كائن (أو وظيفة).

وبالمثل ، إذا كانت وظيفة عضو ما يسمى ودعوة صريحة قالب الحجج ثم المترجم يحتاج إلى معرفة لعلاج < كما في بداية قالب الحجة قائمة وليس أقل من المشغل:

template <typename T>
void foo (B<T> & b)
{
  b.template bar<int> (0); // 'bar' is a template, '<' is start of arg list
  b.Y < 10;                // 'Y' is an object, '<' is less than operator
}

دون template, المحول البرمجي يفترض أن < هو أقل من المشغل ، حتى يولد خطأ في بناء الجملة عندما يرى int> لأن هذا ليس تعبير.

هذه التلميحات هي المطلوبة حتى عند تعريف قالب مرئيا.والسبب هو أن صريح التخصص قد تغيير لاحق التعريف الذي هو في الواقع اختيار:

template <typename T>
class B
{
  template <typename S>
  void a();
};

template <typename T>
void foo (B<T> & b)
{
  b.a < 10;            // 'B<int>::a' is a member object
}

template <>
class B<int>
{
  int a;
};

نصائح أخرى

استخدم إما فقط

original.to_string();

وأو، إذا كنت حقا بحاجة إلى المتخصصين نوع،

original.template to_string<char, char_traits<char>, allocator<char> >();

وفيما يلي جمعت بالنسبة لي (باستخدام 3.4.4 دول مجلس التعاون الخليجي):

#include <bitset>
#include <string>

using namespace std;

template <int N, int M> 
bitset<N> slice_bitset(const bitset<M> &original, size_t start) 
{   
  string str = original.to_string();
  string newstr = str.substr(start, N);    
  return bitset<N>(newstr);
}

int main() 
{ 
  return 0; 
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top