将项目从VS2017转移到Linux下产生的诸多编译错误

前段时间把项目从windows挪到Linux下编译,过程中发现了许多问题,原本在VS下编译没问题的代码在gcc底下就大量报错,解决了很久,其中大部分是同事编码不规范的原因,剩下错误都是精华,今天特意整理了一下,重现一遍。本次编译GCC版本为7.3。

1. typedef/using changes meaning of ‘…’ from ‘…’

在这里插入图片描述
在这里插入图片描述
这个问题的出在42行,编译器认为这个声明不正确,因为Delegate里边根本就没有Invoker模版,gcc在编译这段代码的时候不知道这个Invoker是Delegate::Invoker还是::Invoker,而且改变了15行定义的Invoker模版的意义。实际上这个代码只是想给全局的Invoker模版在类里起个别名,如果要编译通过,应该在Invoker<TReturn, TArgs…>前边加上::,表示引用的是全局的Invoker模版。对这个问题的详细解释在 https://stackoverflow.com/questions/12187549/typedef-changes-meaning?r=SearchResults&s=1|140.9261

2. explicit specialization in non-namespace scope … / template-id … in declaration of primary template

在这里插入图片描述
在这里插入图片描述
由于_FillDataItem是class CommonDataSync的模版成员函数,类的定义范围不属于命名空间,报错的信息也说明了对模版函数的非命名空间显式特例化是错误的,解决这个问题的办法有两个:一个是将特例化方法写在类的定义外边,另一个是将这个函数改成重载的函数而不是模版特例化的。

3. pasting “::” and … does not give a valid preprocessing token

在这里插入图片描述
这个问题是因为预处理连接符号"##",它将"::“和宏定义参数NAME在预处理阶段连接在一起,##并不是简单的字符串拼接,他让”::“与NAME组成了一个token。实际上,正确的预处理token有3个,即"EntityCall”,"::",宏定义参数NAME。这个问题只要把"##"去掉就解决了。

4. class … has no member named …

在这里插入图片描述在这里插入图片描述
产生这个问题是因为函数的后置返回类型使用了decltype表达式,在这个类方法定义的位置以前并没有"_run"方法,decltype在推倒类型的时候就会认为没有这个方法,实际上这个方法写在了比较后边的位置。这也说明了编译器解析类内结构和分析类方法返回类型至少是同时执行的。解决这个问题可以既将_run写在这个函数的前边,也可以将decltype去掉。没有了decltype,编译器会先解析好类的结构,知道类有哪些方法,再次推倒该函数返回类型的时候就找得到"_run"了。这种问题取决于编译器的实现,VS就没这种问题。

5. expected primary-expression before …

当一个对象在其他地方想要调用自己的一个模板成员方法的话,可能会写成这样:

class TestClass{
public:
  template<typename T>
  void TemplateMemFunc(T&& t) {
      ...
  }
};

template<typename T>
class TestClass_T {
public:
    void MemFunc(T&& t) {
        t.TemplateMemFunc<int>(1);
    }
};

此时会报错。这意味着编译器不知道TemplateMemFunc是模板成员方法,编译器以为这是一个成员、嵌套类或者是typedef定义的类型别名,此处的<>会被解析成小于号和大于号。如果想让编译器理解为对象在调用自己的模板成员方法,只需要写成:

t.template TemplateMemFunc<int>(1);

详细内容见https://blog.csdn.net/luoshabugui/article/details/92841658

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值