如何解决gcc-3.4 bug(或者这可能不是bug)?

时间:2010-03-02 06:59:05

标签: c++ gcc

以下代码失败并显示错误消息:

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类的级别上解决它,或者我的代码可能是错的,如果有的话?

修改

Bugs related to template-functions in GCC 3.4.6说我需要使用关键字template,但我应该吗?

这是一个错误吗?我是否必须撰写template关键字?因为在所有其他情况下我不需要?当我使用“.c_str()”成员函数时,我没有必要写它。

为什么gcc-4并不总是一个选项

在Cygwin

下使用gcc-4编译时,此程序无法启动
#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;
}

这段代码不能在OpenSolaris 2009下用gcc-4.3编译 - 破坏概念检查......

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

3 个答案:

答案 0 :(得分:2)

这是旧编译器中的错误。较新的海湾合作委员会,从4.0到(未发布的)4.5,接受它,正如他们应该的那样。它是标准的C ++。 (英特尔和Comeau也接受它。)

关于cygwin和opensolaris,当然gcc-3.4不是唯一的选择:较新的版本(发布的4.4.3,或未发布的4.5分支)在这些操作系统上运行良好。对于cygwin,它是官方发行版的一部分(请参阅gcc4*in the list)。对于opensolaris,您可以自己编译(有关如何操作的说明可以在Google上轻松找到)。

答案 1 :(得分:2)

如其他地方所述,这似乎是一个编译器错误。很公平;那些存在。以下是您对此所做的事情:

#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__作为x.y.z版本号的y和z。

答案 2 :(得分:1)

我会尝试使用不同的解决方法,因为添加template消歧器不正确,如果稍后转移到其他编译器将会中断。

我不知道真正的代码,但是传递常规std::string似乎有用(选项1:避免转换为const char *只是为了创建一个临时代码)或者你可以提供一个重载的{{ 1}}以translate作为参数(如果编译器没有在那里抱怨),具体取决于您的要求。