2

次のコードを 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 クラスの定義の開始):

Core\SVS\src\filters\absval.cpp(8) : error C2504: 'typed_map_filter' : base class undefined Core\SVS\src\filters\absval.cpp(8) : error C2143: syntax error : missing ',' before '<' Core\SVS\src\filters\absval.cpp(12) : error C4430: missing type specifier - int assumed. >Note: C++ does not support default-int Core\SVS\src\filters\absval.cpp(12) : error C2143: syntax error : missing ',' before '*' Core\SVS\src\filters\absval.cpp(10) : error C2059: syntax error : '<' Core\SVS\src\filters\absval.cpp(14) : error C2065: 'params' : undeclared identifier Core\SVS\src\filters\absval.cpp(14) : error C2227: left of '->empty' must point to >class/struct/union/generic type
       type is ''unknown-type'' Core\SVS\src\filters\absval.cpp(17) : error C2065: 'filter_val' : undeclared identifier Core\SVS\src\filters\absval.cpp(17) : error C2065: 'fv' : undeclared identifier Core\SVS\src\filters\absval.cpp(17) : error C2065: 'params' : undeclared identifier Core\SVS\src\filters\absval.cpp(17) : error C2227: left of '->begin' must point to >class/struct/union/generic type
       type is ''unknown-type'' Core\SVS\src\filters\absval.cpp(17) : error C2227: left of '->second' must point to >class/struct/union/generic type Core\SVS\src\filters\absval.cpp(18) : error C2065: 'fv' : undeclared identifier Core\SVS\src\filters\absval.cpp(18) : error C3861: 'get_filter_val': identifier not found Core\SVS\src\filters\absval.cpp(21) : error C3861: 'fabs': identifier not found Core\SVS\src\filters\absval.cpp(22) : error C2065: 'changed' : undeclared identifier Core\SVS\src\filters\absval.cpp(22) : error C2065: 'res' : undeclared identifier Core\SVS\src\filters\absval.cpp(23) : error C2065: 'res' : undeclared identifier Core\SVS\src\filters\absval.cpp(29) : error C2065: 'input' : undeclared identifier Core\SVS\src\filters\absval.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 の静的アナライザーも何も検出しません。何か案は?

4

1 に答える 1