gcc 7.5.0 模板编译报错 error: expected primary-expression before ‘>‘ token 问题解决

gcc 7.5.0 模板编译报错 error: expected primary-expression before ‘>‘ token 问题解决


1、问题

前段时间写了一段关于模板的代码,大概情形是这样的:
定义一个非模板类A,有一个模板函数,又定义了一个模板类B,B中也定义了一个模板函数
将A作为B的模板参数进行实例化,在B的模板函数中调用A的模板函数。
在ubuntu18.04中编译(GCC 7.5.0)报错,尝试在ubuntu20.04
编译,依然报错。(在VS2015、VS2019编译都没问题,ubuntu16.04中的GCC 5.4.0也没问题)
在这里插入图片描述

2、问题分析

模板在实例化时,没有识别调用的A函数也模板函数,认为函数模板参数字符非法。

3、解决方法

需要使用template关键字来显式标记模板成员函数。
即在类B的模板函数Get中,显式的标记模板函数a_instance.template Get<T>(),而不是直接调用a_instance.Get<T>(),见完整代码。

4、完整代码

完整代码如下:

#include <iostream>
#include <string>

// 类A的定义
class A {
public:

	// 模板成员函数
	template<typename T>
	void Set(T value) {
		std::cout << "A::Set called with value: " << value << std::endl;
	}
	// 模板成员函数,返回一个默认构造的T
	template<typename T>
	T Get() {
		std::cout << "A::Get called, returning default-constructed T" << std::endl;
		return T();
	}
};

// 模板类B的定义
template<typename TA>
class B {
private:
	TA a_instance; // A的实例作为B的成员
public:
	// 模板成员函数
	template<typename T>
	void Set(T value) 
	{
		std::cout << "B::Set called with value: " << value << std::endl;
		a_instance.Set(value);
		//a_instance.Set<T>(value);//在GCC 7.5.0 及以上版本编译失败
	}

	// 模板成员函数,返回一个默认构造的T
	template<typename T>
	T Get() 
	{
		std::cout << "B::Get called, calling A::funcA and returning its result" << std::endl;
		// 调用A的模板成员函数并返回其结果
		return a_instance.template Get<T>();
		//以下代码在GCC 7.5.0 及以上版本编译失败
		//return a_instance.Get<T>();
	}
};

int main() {
	// 创建B<A>的对象,即B的模板参数为A
	B<A> b;

	int int_value = b.Get<int>();

	std::string strSet = "set string";
	b.Set<std::string>(strSet);

	return 0;
}

在B::Set函数中,调用“a_instance.Set(value)”,不用显式的指定模板参数,因为A中Set接口通过入参,可以推导出模板类型,A中Get形参为空,因此不能推导出模板类型。

C++ 单元测试代码中,出现 `expected primary-expression before ‘(’ token` 或 `expected primary-expression before ‘>’ token` 等错误,通常与语法结构、模板使用、宏定义或编译器支持标准有关。以下是可能导致此类错误的原因及解决方法: ### 语法错误或表达式结构不完整 该错误通常表示编译器在解析代码时遇到了不完整的表达式或语法结构。例如: ```cpp int result = (a + b; // 缺少右括号 ``` 或 ```cpp int value = someFunction ( // 缺少参数或括号不匹配 ``` 确保所有表达式结构完整,括号匹配,语句以分号结尾。 ### 模板语法问题模板代码中,若模板参数列表未正确闭合或嵌套模板使用不当,也可能导致此类错误。例如: ```cpp std::vector<std::pair<int, int>> vec; // 正确写法 std::vector<std::pair<int, int> > vec; // 在 C++11 之前必须写成这样 ``` 在使用较旧版本的 GCC 编译器(如 GCC 7.5.0)时,嵌套模板可能需要额外的空格分隔尖括号,否则会报 `expected primary-expression before ‘>’ token` 错误 [^4]。 ### 宏定义或条件编译问题 宏定义可能导致代码结构在预处理阶段被破坏,例如: ```cpp #define LOG(x) std::cout << x << std::endl LOG("Value: " << value); // 若宏定义未正确闭合可能导致语法错误 ``` 确保宏定义完整,必要时使用 `do { ... } while (0)` 结构包裹多行宏代码。 ### CUDA 代码使用 g++ 编译导致错误 若代码中包含 CUDA 特有的语法(如 `<<<grid, block>>>`),使用 g++ 编译器将无法识别这些语法结构,导致 `expected primary-expression before ‘>>>’ token` 错误。解决方法是将文件后缀改为 `.cu`,并使用 `nvcc` 编译器进行编译: ```bash nvcc CoreUnitTest.cu -o CoreUnitTest ``` 该方法适用于在 NVIDIA Jetson 设备等嵌入式平台上编译 CUDA 代码 [^3]。 ### 标识符未声明 若错误信息中还包含“未声明标识符”,则可能是变量、函数或命名空间未正确引入。例如: ```cpp cout << "Test"; // 若未包含 <iostream> 或未使用 std 命名空间 ``` 应修改为: ```cpp #include <iostream> using namespace std; cout << "Test"; ``` ### 多编译器兼容性问题 某些代码在 Windows 平台使用 MSVC 编译器可以正常编译,但在 Linux 平台使用 g++ 编译器时出现 `expected primary-expression before ‘<<’ token` 等错误,可能是因为 g++ 对模板和运算符重载的解析更为严格 [^2]。确保模板函数或运算符重载的定义和使用方式符合标准 C++ 规范。 ### 第三方库版本不兼容 在使用第三方库(如 apex)时,若版本不兼容也可能导致类似错误。例如: ```bash error: expected primary-expression before ‘>’ token ``` 解决方法是回退到已知稳定的版本,如使用 Git 提交哈希值指定版本: ```bash git checkout f3a960f80244cf9e80558ab30f7f7e8cbf03c0a0 ``` 这适用于某些依赖 CUDA 的库在特定版本下编译失败的情况 [^5]。 ### 示例代码 以下是一个可能引发该错误的测试用例片段及修复方法: ```cpp TEST(CoreUnitTest, WaitEventTest) { std::vector<int> data = {1, 2, 3}; EXPECT_EQ(data.size(), 3); // 正确写法 } ``` 若写成: ```cpp EXPECT_EQ(data.size, 3); // 缺少括号,将导致编译错误 ``` 则会报 `expected primary-expression before ‘)’ token` 错误。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值