2

This question was marked duplicate to a solution that uses boost for keeping dynamic polymorphism, even though i stated explicitly that I can't use boost.

I want to have multiple contexts that are instanciated somewhere else. Now we want to set key-value variables to some value of type T, context-dependent.

A variable class is a handle to set an arbitrary type to some value.

Each context handles the variable setting differently (namely these are graphics backends.) For that, the Context::magically_set method could be specialized for each supported T.

But each context handles each supported T differently.

Here's my "working" code if virtual member functions could be templated:

class Context {
public:
    template<typename T>
    virtual void magically_set(const T &value);
};

class ContextA : public Context {
public:
    template<typename T>
    void magically_set(const std::string &name, const T &value) override;
    // somewhere else: T-specific implementation for this context.
};

class ContextB : public Context {
public:
    template<typename T>
    void magically_set(const std::string &name, const T &value) override;
    // somewhere else: T-specific implementation for this different context.
};

template<typename T>
class Variable {
public:
    Variable(std::string name, Context *context)
        : name{name}, context{context} {}

    void set(const T &value) {
        this->context->magically_set(this->name, value);
    }

    std::string name;
    Context *context;
};

and the usage:

ContextB ctx_b;
Variable<float> test{"index", &ctx_b};
Variable<vec3> vectest{"color", &ctx_b};
test.set(0.1337f);
vectest.set({0.0, 0.0, 1.0});

How can I make this work? I can use anything supported by c++14, but no boost.

4
  • Does context has a limited number of T supported ? Commented Aug 28, 2015 at 16:52
  • Yes, because each T needs special handling (we're talking about shader uniforms here.) Commented Aug 28, 2015 at 16:58
  • 2
    So you may have several virtual void magically_set, one by supported type. Commented Aug 28, 2015 at 17:01
  • Why was the question flagged duplicate? I stated that I can't use boost, and the "duplicate" uses boost as the only option for maintaining dynamic polymorphism... @Jarod42, yes this is a good idea although it will severely clutter the base class. Thanks though! Commented Aug 28, 2015 at 23:22

1 Answer 1

1

If you don't have problems to supply the Context to the Variable you could do something like the following:

template<typename T, typename C>
class Variable {
public:
    Variable(std::string name, C &context)
        : name{name}, context{context} {}

    void set(const T &value) {
        this->context->magically_set(this->name, value);
    }

    std::string name;
    C &context;
};

you now have to declare the Variables as follows:

typedef ContextB ActiveContext;

ContextB ctx_b;
Variable<float, ActiveContext> test{"index", ctx_b};
Variable<vec3, ActiveContext> vectest{"color", ctx_b};
test.set(0.1337f);
vectest.set({0.0, 0.0, 1.0});

PS: you should make Variable::name and Variable::context private.

Sign up to request clarification or add additional context in comments.

1 Comment

Sorry, but this would lead to a compiletime context dependency, but the context selection must happen dynamically.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.