Как обойти ошибку gcc-3.4 (или, может быть, это не ошибка)? - PullRequest
2 голосов
/ 02 марта 2010

Следующий код завершается ошибкой с сообщением об ошибке:

t.cpp: In function `void test()':
t.cpp:35: error: expected primary-expression before '>' token
t.cpp:35: error: expected primary-expression before ')' token

Теперь я не вижу проблем с кодом, и он компилируется с gcc-4.x и MSVC 2005, но не с gcc-3.4 (который все еще довольно популярен на некоторых платформах).

#include <string>
#include <iostream>

struct message {
        message(std::string s) : s_(s) {}
        template<typename CharType>
        std::basic_string<CharType> str()
        {
                return std::basic_string<CharType>(s_.begin(),s_.end());
        }
private:
        std::string s_;
};


inline message translate(std::string const &s)
{
        return message(s);
}


template<typename TheChar>
void test()
{
        std::string s="text";
        std::basic_string<TheChar> t1,t2,t3,t4,t5;

        t1=translate(s).str<TheChar>(); // ok

        char const *tmp=s.c_str();
        t2=translate(tmp).str<TheChar>(); // ok

        t3=message(s.c_str()).str<TheChar>(); // ok

        t4=translate(s.c_str()).str<TheChar>(); // fails

        t5=translate(s.c_str()).template str<TheChar>(); // ok

        std::cout << t1 <<" " << t2 <<" " << t3 << " " << t4 << std::endl;
}

int main()
{
        test<char>();
}

Возможно ли обойти его на уровне функции translate и класса message, или, возможно, мой код неверен, если да, то где?

Редактировать:

Ошибки, связанные с шаблонными функциями в GCC 3.4.6 , говорят, что мне нужно использовать ключевое слово template, но должен ли я?

Это ошибка?Должен ли я написать ключевое слово template?Потому что во всех остальных случаях мне это не нужно?И это довольно проводной, мне не нужно писать это, когда я использую функцию-член ".c_str ()".

Почему gcc-4 не всегда опция

Эта программа не запускается при компиляции с gcc-4 под Cygwin

#include <iostream>
#include <locale>

class bar : public std::locale::facet  {
public:
        bar(size_t refs=0) : std::locale::facet(refs)
        {
        }
        static std::locale::id id;
};

std::locale::id bar::id;


using namespace std;

int main()
{
        std::locale l=std::locale(std::locale(),new bar());
        std::cout << has_facet<bar>(l) << std::endl;
        return 0;
}

И этот код не компилируется с gcc-4.3 под OpenSolaris 2009 - проверки нарушенных концепций ...

#include <map>
struct tree {
   std::map<int,tree> left,right;
};

Ответы [ 3 ]

2 голосов
/ 02 марта 2010

Как уже упоминалось в другом месте, это похоже на ошибку компилятора. Справедливо; те существуют. Вот что вы делаете с этими:

#if defined(__GNUC__) && __GNUC__ < 4
// Use erroneous syntax hack to work around a compiler bug.
t4=translate(s.c_str()).template str<TheChar>();
#else
t4=translate(s.c_str()).str<TheChar>();
#endif

GCC всегда определяет __GNUC__ для основного номера версии компилятора. Если вам это нужно, вы также получите __GNUC_MINOR__ и __GNUC_PATCHLEVEL__ для y и z номера версии x.y.z.

2 голосов
/ 02 марта 2010

Это ошибка в старом компиляторе. Более новые GCC, от 4.0 до (пока не выпущенные) 4.5, принимают его, как они должны. Это стандарт C ++. (Intel и Comeau тоже это принимают.)

Что касается cygwin и opensolaris, конечно, gcc-3.4 - не единственный вариант: более новые версии (выпущенная 4.4.3 или неизданная ветвь 4.5) отлично работают на этих ОС. Для cygwin это часть официального дистрибутива (см. gcc4* packages в списке ). Для opensolaris вы можете скомпилировать его самостоятельно (а инструкции о том, как это сделать, можно легко найти в Google).

1 голос
/ 02 марта 2010

Я бы попробовал использовать другой обходной путь, так как добавление двусмысленности template там некорректно и сломается, если вы позже перейдете к другому компилятору.

Я не знаю реального кода, но кажется, что передача обычного std::string работает (вариант 1: избегайте преобразования в const char * просто для создания временного), или вы можете предоставить перегруженный translate, который требует const char* в качестве аргумента (если компилятор там не жалуется), в зависимости от ваших требований.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...