基类未定义的 Visual Studio 2010



使用 Visual Studio 2010 编译以下代码:

#include "filter.h"
#include "filter_table.h"
#include "scene.h"
#include "common.h"
using namespace std;
class absval_filter : public typed_map_filter<float> {
public:
absval_filter(filter_input *input) : typed_map_filter<float>(input) {}
bool compute(const filter_param_set *params, bool adding, float &res, bool &changed) {
    float newres;
    if (params->empty()) {
        return false;
    }
    filter_val *fv = params->begin()->second;
    if (!get_filter_val(fv, newres)) {
        return false;
    }
    newres = fabs(newres);
    changed = (newres != res);
    res = newres;
    return true;
}
};

产生以下错误(第 8 行 = 类 absval_filter 定义的开始):

CoreSVSsrcfiltersabsval.cpp(8) : error C2504: 'typed_map_filter' : base class undefined CoreSVSsrcfiltersabsval.cpp(8) : error C2143: syntax error : missing ',' before '<' CoreSVSsrcfiltersabsval.cpp(12) : error C4430: missing type specifier - int assumed. >Note: C++ does not support default-int CoreSVSsrcfiltersabsval.cpp(12) : error C2143: syntax error : missing ',' before '*' CoreSVSsrcfiltersabsval.cpp(10) : error C2059: syntax error : '<' CoreSVSsrcfiltersabsval.cpp(14) : error C2065: 'params' : undeclared identifier CoreSVSsrcfiltersabsval.cpp(14) : error C2227: left of '->empty' must point to >class/struct/union/generic type
       type is ''unknown-type'' CoreSVSsrcfiltersabsval.cpp(17) : error C2065: 'filter_val' : undeclared identifier CoreSVSsrcfiltersabsval.cpp(17) : error C2065: 'fv' : undeclared identifier CoreSVSsrcfiltersabsval.cpp(17) : error C2065: 'params' : undeclared identifier CoreSVSsrcfiltersabsval.cpp(17) : error C2227: left of '->begin' must point to >class/struct/union/generic type
       type is ''unknown-type'' CoreSVSsrcfiltersabsval.cpp(17) : error C2227: left of '->second' must point to >class/struct/union/generic type CoreSVSsrcfiltersabsval.cpp(18) : error C2065: 'fv' : undeclared identifier CoreSVSsrcfiltersabsval.cpp(18) : error C3861: 'get_filter_val': identifier not found CoreSVSsrcfiltersabsval.cpp(21) : error C3861: 'fabs': identifier not found CoreSVSsrcfiltersabsval.cpp(22) : error C2065: 'changed' : undeclared identifier CoreSVSsrcfiltersabsval.cpp(22) : error C2065: 'res' : undeclared identifier CoreSVSsrcfiltersabsval.cpp(23) : error C2065: 'res' : undeclared identifier CoreSVSsrcfiltersabsval.cpp(29) : error C2065: 'input' : undeclared identifier CoreSVSsrcfiltersabsval.cpp(29) : fatal error C1903: unable to recover from previous error(s); stopping compilation

类 "typed_map_filter" 在 filter.h 中定义:

#ifndef FILTER_H
#define FILTER_H
#include <iostream>
#include <string>
#include <list>
#include <map>
#include <sstream>
#include <iterator>
#include "linalg.h"
#include "sgnode.h"
#include "scene.h"
#include "common.h"
...
/*
 The filter is the basic query unit in SVS. Each filter takes a list of
 parameter sets generated by the filter_input class and produces a single
 result list. Soar can "mix-and-match" filters by plugging their outputs
 into inputs of other filters. This is done by specifying the desired
 filter plumbing on the SVS command link.
 Filter results are updated once every output phase. Updating a filter's
 result is recursive: the filter will first request an update on its
 input, which in turn requests updates on all filters feeding into the
 input. Filters should also try to cache results when possible to avoid
 unnecessary computation.
*/
class filter {
public:
filter() {
    input = new null_filter_input();
}
filter(filter_input *in) : input(in) {
    if (input == NULL) {
        input = new null_filter_input();
    }
}
virtual ~filter() {
    delete input;
}
std::string get_error() {
    return errmsg;
}
bool is_error() {
    return !errmsg.empty();
}
void set_error(std::string msg) {
    errmsg = msg;
    result.clear();
}
void clear_error() {
    errmsg.clear();
}
void add_result(filter_val *v, const filter_param_set *p) {
    result.add(v);
    result2params[v] = p;
}
bool get_result_params(filter_val *v, const filter_param_set *&p) {
    return map_get(result2params, v, p);
}
void remove_result(filter_val *v) {
    result.remove(v);
    result2params.erase(v);
}
void change_result(filter_val *v) {
    result.change(v);
}
filter_result *get_result() {
    return &result;
}
bool update() {
    if (!input->update()) {
        set_error("Errors in input");
        result.clear();
        input->reset();
        return false;
    }
    if (!update_results()) {
        result.clear();
        input->reset();
        return false;
    }
    input->clear_changes();
    return true;
}
const filter_input *get_input() const {
    return input;
}
private:
virtual bool update_results() = 0;
filter_input *input;
filter_result result;
std::string errmsg;
std::map<filter_val*, const filter_param_set*> result2params;
};

/*
 This type of filter assumes a one-to-one mapping of results to input
 parameter sets. It's also assumed that each result is only dependent
 on one parameter set. This is in contrast to filters that perform some
 kind of quantification over its inputs; returning the closest object,
 for example.
*/
class map_filter : public filter {
public:
map_filter(filter_input *input) : filter(input) {}
/*
 All created filter_vals are owned by the result list and cleaned
 up there, so don't do it here.
*/
virtual ~map_filter() {}
/*
 Compute the result from parameters. If called with a new
 parameter set, res will be NULL, and the implementation should
 set it to a new filter_val object (which will be owned by the
 result list). Otherwise, res will point to a valid filter_val and
 the implementation should change its value. If the value is
 actually changed, the changed output argument should be set to
 true. The implementation should return false if an error occurs.
 */
virtual bool compute(const filter_param_set *params, filter_val *&res, bool &changed) = 0;
/*
 Some derived classes might allocate memory associated with each
 result. They should override this function so they know when
 to deallocate that memory.
*/
virtual void result_removed(const filter_val *res) { }
/*
 Sometimes the function that maps from parameter set to result
 is conditioned on things other than the parameter set, such as
 the state of the scene graph. A derived class that implements
 such a function should explicitly mark a result as needing to be
 recomputed even when its associated parameter set doesn't change.
*/
void mark_stale(const filter_param_set *s) {
    stale.push_back(s);
}
bool update_results() {
    const filter_input* input = get_input();
    std::vector<const filter_param_set*>::iterator j;
    for (int i = input->first_added(); i < input->num_current(); ++i) {
        filter_val *v = NULL;
        bool changed = false;
        if (!compute(input->get_current(i), v, changed)) {
            return false;
        }
        add_result(v, input->get_current(i));
        io_map[input->get_current(i)] = v;
    }
    for (int i = 0; i < input->num_removed(); ++i) {
        io_map_t::iterator r = io_map.find(input->get_removed(i));
        assert(r != io_map.end());
        result_removed(r->second);
        remove_result(r->second);
        io_map.erase(r);
    }
    for (int i = 0; i < input->num_changed(); ++i) {
        if (!update_one(input->get_changed(i))) {
            return false;
        }
    }
    for (j = stale.begin(); j != stale.end(); ++j) {
        if (!update_one(*j)) {
            return false;
        }
    }
    stale.clear();
    return true;
}
void reset() {}
private:
bool update_one(const filter_param_set *params) {
    filter_val *v = io_map[params];
    bool changed = false;
    if (!compute(params, v, changed)) {
        return false;
    }
    if (changed) {
        change_result(v);
    }
    return true;
}
typedef std::map<const filter_param_set*, filter_val*> io_map_t;
io_map_t io_map;
std::vector<const filter_param_set*> stale;
};
/*
 User-defined filters should derive from this class so that they don't
 have to work with filter_val* directly. Assumes that the filter only
 returns one type of result.
*/
template <typename T>
class typed_map_filter : public map_filter {
public:
typed_map_filter(filter_input *input) : map_filter(input) {}
virtual ~typed_map_filter() {}
virtual bool compute(const filter_param_set *params, bool adding, T &res, bool &changed) = 0;
virtual void result_removed(const T &res) { }
private:
bool compute(const filter_param_set *params, filter_val *&res, bool &changed) {
    bool success;
    T val;
    if (res != NULL) {
        success = get_filter_val(res, val);
        assert(success);
    }
    success = compute(params, res == NULL, val, changed);
    if (!success) {
        return false;
    }
    if (!res) {
        res = new filter_val_c<T>(val);
    } else {
        success = set_filter_val(res, val);
        assert(success);
    }
    return true;
}
void result_removed(const filter_val *res) {
    T val;
    bool success = get_filter_val(res, val);
    assert(success);
    result_removed(val);
}
};
...
#endif

我还手动检查了递归包含,但没有发现。 这段代码在 Linux 和 Mac OS X 上使用 gcc 编译得很好(并且运行得很好);它在Mac OS X上使用clang也可以很好地编译。 Clang的静态分析器也一无所获。 有什么想法吗?

(在问题编辑中回答。 转换为社区维基答案。请参阅将问题的答案添加到问题本身时,适当的操作是什么?)

OP写道:

解决。问题最终成为包含问题。

cl /FobuildCoreSVSsrcfiltersabsval.obj /c CoreSVSsrcfiltersabsval.cpp /TP /nologo /EHsc /D _CRT_SECURE_NO_DEPRECATE /D _WIN32 /W2 /Z7 /DEBUG /D _USRDLL /ICoreshared /ICorepcre /ICoreSoarKernelsrc /ICoreElementXMLsrc /ICoreKernelSMLsrc /ICoreConnectionSMLsrc /ICoreClientSMLsrc /ICoreCLIsrc "/IC:Program FilesMicrosoft Visual Studio 10.0VCINCLUDE" "/IC:Program FilesMicrosoft SDKsWindowsv7.0Ainclude" /ICoreSVSsrc /ICoreSVSsrcfilters /ICoreSVSsrcmodels /ICoreSVSsrcalgorithms /ICoreSVSeigen /ICoreSVSbulletinclude

cl /FobuildCoreSVSsrcfiltersabsval.obj /c CoreSVSsrcfiltersabsval.cpp /TP /nologo /EHsc /D _CRT_SECURE_NO_DEPRECATE /D _WIN32 /W2 /Z7 /DEBUG /D _USRDLL /ICoreshared /ICorepcre /ICoreSoarKernelsrc /ICoreElementXMLsrc /ICoreKernelSMLsrc /ICoreConnectionSMLsrc /ICoreClientSMLsrc /ICoreCLIsrc /ICoreSVSsrc /ICoreSVSsrcfilters /ICoreSVSsrcmodels /ICoreSVSsrcalgorithms /ICoreSVSeigen /ICoreSVSbulletinclude "/IC:Program FilesMicrosoft Visual Studio 10.0VCINCLUDE" "/IC:Program FilesMicrosoft SDKsWindowsv7.0Ainclude"

不知何故,窗口标题正在搞砸包含并产生导致此问题的问题。

最新更新