我对C ++比较陌生,所以当我看到这些涉及错误的怪异模板时,我有点茫然。
这是我的代码:
#include "scene.hpp"
#include <map>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
// projects a ray from the eyepoint through (x, y) in the image plane
Ray Camera::project_ray(int x, int y){
}
class scene_parser{
public:
class unimplemented_exception {};
class unknown_command_exception {};
class malformed_command_exception {};
scene_parser(Scene &s);
void parse(const std::string &filename);
private:
PixelBufferPTR current_texture;
Colour current_material_colour;
Material current_material;
typedef void (scene_parser::*parsefunc )(std::vector<std::string>);
std::map<std::string, parsefunc> funcMap;
void init_funcMap();
void apply_func(const std::vector<std::string> &line);
// methods which parse the scene file
// they each receive a line of the file, tokenized on whitespace
void camera_from(std::vector<std::string> line);
void camera_target(std::vector<std::string> line);
void camera_forw(std::vector<std::string> line);
void camera_up(std::vector<std::string> line);
void camera_angle(std::vector<std::string> line);
void camera_resolution(std::vector<std::string> line);
void sphere(std::vector<std::string> line);
void tsphere(std::vector<std::string> line);
void texture(std::vector<std::string> line);
void mesh(std::vector<std::string> line) {throw unimplemented_exception();}
void background(std::vector<std::string> line);
void ambient_light(std::vector<std::string> line);
void parallel_light(std::vector<std::string> line);
void point_light(std::vector<std::string> line);
void spot_light(std::vector<std::string> line) {throw unimplemented_exception();}
void material(std::vector<std::string> line);
void render(std::vector<std::string> line);
void trace_depth(std::vector<std::string> line);
};
scene_parser::scene_parser(Scene &s) : current_material_colour(0, 0, 0), current_material(0, 0, 0, 0, 0) {
init_funcMap();
}
void scene_parser::init_funcMap(){
funcMap["camera_from"] = &scene_parser::camera_from;
funcMap["camera_target"] = &scene_parser::camera_target;
funcMap["camera_forw"] = &scene_parser::camera_forw;
funcMap["camera_up"] = &scene_parser::camera_up;
funcMap["camera_angle"] = &scene_parser::camera_angle;
funcMap["camera_resolution"] = &scene_parser::camera_resolution;
funcMap["sphere"] = &scene_parser::sphere;
funcMap["tsphere"] = &scene_parser::tsphere;
funcMap["texture"] = &scene_parser::texture;
funcMap["mesh"] = &scene_parser::mesh;
funcMap["background"] = &scene_parser::background;
funcMap["ambient_light"] = &scene_parser::ambient_light;
funcMap["parallel_light"] = &scene_parser::parallel_light;
funcMap["point_light"] = &scene_parser::point_light;
funcMap["spot_light"] = &scene_parser::spot_light;
funcMap["material"] = &scene_parser::material;
funcMap["render"] = &scene_parser::render;
funcMap["trace_depth"] = &scene_parser::trace_depth;
}
void scene_parser::apply_func(const std::vector<std::string> &line){
if(line.size() != 0){
std::map<std::string, parsefunc>::iterator it = funcMap.find(line[0]);
if(it == funcMap.end()) throw unknown_command_exception();
else{
parsefunc f = it->second;
this->*f(line); //line 86
}
}
}
void scene_parser::parse(const std::string &filename){
std::vector<std::string> lines = tokenize_string(file_to_string(filename), "\n");
std::vector<std::vector<std::string> > tokenized_lines;
tokenized_lines.resize(lines.size());
std::transform(lines.begin(), lines.end(), tokenized_lines.begin(), tokenized_lines.end(), std::bind2nd(std::ptr_fun(tokenize_string), std::string(" "))); //line 97
std::for_each(tokenized_lines.begin(), tokenized_lines.end(), std::mem_fun(&scene_parser::apply_func)); //line 99
}
这是tokenize_string
std::vector<std::string> tokenize_string(const std::string &s, const std::string &split_chars);
以下是错误:
Scene.cpp: In member function ‘void scene_parser::apply_func(const std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&)’:
Scene.cpp:86: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘f (...)’, e.g. ‘(... ->* f) (...)’
In file included from /usr/include/c++/4.4/bits/stl_function.h:712,
from /usr/include/c++/4.4/memory:66,
from light.hpp:4,
from Scene.hpp:4,
from Scene.cpp:1:
/usr/include/c++/4.4/backward/binders.h: At global scope:
/usr/include/c++/4.4/backward/binders.h: In instantiation of ‘std::binder2nd<std::pointer_to_binary_function<const std::string&, const std::string&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >’:
Scene.cpp:97: instantiated from here
/usr/include/c++/4.4/backward/binders.h:152: error: ‘typename _Operation::result_type std::binder2nd<_Operation>::operator()(typename _Operation::first_argument_type&) const [with _Operation = std::pointer_to_binary_function<const std::string&, const std::string&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]’ cannot be overloaded
/usr/include/c++/4.4/backward/binders.h:146: error: with ‘typename _Operation::result_type std::binder2nd<_Operation>::operator()(const typename _Operation::first_argument_type&) const [with _Operation = std::pointer_to_binary_function<const std::string&, const std::string&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]’
In file included from /usr/include/c++/4.4/algorithm:62,
from Scene.cpp:5:
/usr/include/c++/4.4/bits/stl_algo.h: In function ‘_OIter std::transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation) [with _IIter1 = __gnu_cxx::__normal_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, _IIter2 = __gnu_cxx::__normal_iterator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*, std::vector<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::allocator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >, _OIter = __gnu_cxx::__normal_iterator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*, std::vector<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::allocator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >, _BinaryOperation = std::binder2nd<std::pointer_to_binary_function<const std::string&, const std::string&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >]’:
Scene.cpp:97: instantiated from here
/usr/include/c++/4.4/bits/stl_algo.h:4741: error: no match for call to ‘(std::binder2nd<std::pointer_to_binary_function<const std::string&, const std::string&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >) (std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&)’
/usr/include/c++/4.4/backward/binders.h:146: note: candidates are: typename _Operation::result_type std::binder2nd<_Operation>::operator()(const typename _Operation::first_argument_type&) const [with _Operation = std::pointer_to_binary_function<const std::string&, const std::string&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]
/usr/include/c++/4.4/bits/stl_algo.h: In function ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*, std::vector<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::allocator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >, _Funct = std::mem_fun1_t<void, scene_parser, const std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&>]’:
Scene.cpp:99: instantiated from here
/usr/include/c++/4.4/bits/stl_algo.h:4200: error: no match for call to ‘(std::mem_fun1_t<void, scene_parser, const std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&>) (std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&)’
/usr/include/c++/4.4/bits/stl_function.h:604: note: candidates are: _Ret std::mem_fun1_t<_Ret, _Tp, _Arg>::operator()(_Tp*, _Arg) const [with _Ret = void, _Tp = scene_parser, _Arg = const std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&]
在Ubuntu 10.10上用gcc 4.4编译。
我很感激任何洞察力。
答案 0 :(得分:2)
Scene.cpp: In member function ‘void scene_parser::apply_func(const std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&)’:
Scene.cpp:86: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘f (...)’, e.g. ‘(... ->* f) (...)’
注意第二行的后半部分。您只需使用括号指向成员函数(PTMF)的括号:
void scene_parser::apply_func(const std::vector<std::string> &line) {
if (line.size() != 0) {
std::map<std::string, parsefunc>::iterator it = funcMap.find(line[0]);
if (it == funcMap.end()) throw unknown_command_exception();
else {
parsefunc f = it->second;
(this->*f)(line); // line 86 (fixed)
}
}
}
我只是使用“正常”for循环来“修复”其他错误;不幸的是,模板错误可能非常糟糕,我也讨厌它。
std::vector<std::vector<std::string> > tokenized_lines;
tokenized_lines.reserve(lines.size());
// c++0x: for (auto const &x : lines) {
for (std::vector<std::string>::const_iterator x = lines.begin(); x != lines.end(); ++x) {
tokenized_lines.push_back(tokenize_string(*x), " "); // no dereference in 0x
tokenized_lines.back().apply_func();
}