C++模板编译错误:在'>'标记之前的预期primary-expression

And*_*w T 35 c++ gcc boost compiler-errors visual-c++

此代码编译并按预期工作(它在运行时抛出,但没关系):

#include <iostream>
#include <boost/property_tree/ptree.hpp>

void foo(boost::property_tree::ptree &pt) 
{
    std::cout << pt.get<std::string>("path"); // <---
}

int main()
{
    boost::property_tree::ptree pt;
    foo(pt);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是只要我添加模板并将foo原型更改为

template<class ptree>
void foo(ptree &pt)
Run Code Online (Sandbox Code Playgroud)

我在GCC中遇到错误:

test_ptree.cpp: In function ‘void foo(ptree&)’:
test_ptree.cpp:7: error: expected primary-expression before ‘>’ token
Run Code Online (Sandbox Code Playgroud)

但MSVC++没有错误!错误在标记的行中<---.再次,如果我将问题线改为

--- std::cout << pt.get<std::string>("path"); // <---
+++ std::cout << pt.get("path", "default value");
Run Code Online (Sandbox Code Playgroud)

错误消失(问题是明确的<std::string>).

Boost.PropertyTree需要Boost> = 1.41.请帮助我理解并修复此错误.


请参阅模板:模板功能与类的模板成员函数不兼容 - 一个类似的流行问题包含其他好的答案和解释.

GMa*_*ckG 59

你需要这样做:

std::cout << pt.template get<std::string>("path");
Run Code Online (Sandbox Code Playgroud)

除了模板成员而不是类型之外template,在相同的情况下使用typename.

(也就是说,由于pt::get依赖于模板参数的模板成员,因此您需要告诉编译器它是一个模板.)

  • 好的。您是否有用于模板使用的特定资源?我出于好奇而问。我的书似乎都没有解决这个问题。 (2认同)
  • 为什么你需要告诉编译器它是一个模板?编译器不应该能够自己解决这个问题吗? (2认同)
  • @HelloGoodbye:我不记得在C++中理论上是否可以让编译器总是正确地推断它,可能不是.问题是没有`template`,它可以被解析为`(pt.get)<std :: string>("path");`,即比较.在这种情况下,类型名称的比较是不可能的,所以它可以弄清楚,但一般来说你将如何解析`pt.val <5>(10)`?添加`template`直接告诉编译器"这是一个函数调用". (2认同)