Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 1094601
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 16, 20262026-05-16T23:59:40+00:00 2026-05-16T23:59:40+00:00

I have a C++ application that executes test cases. It is possible that some

  • 0

I have a C++ application that executes test cases. It is possible that some test cases will depend on output from other test cases.

All test cases implement a basic interface:

/// base class for all test cases
class ITest
{
public:
    virtual void Execute() = 0;
};

Test cases that produce some object that may be useful to other test cases implement this interface:

/// implemented by test cases that provide data to other test cases
template< class Obj >
class IDependency
{
public:
    virtual Obj Get() = 0;
};

Test cases that require data from other test cases implement this interface:

/// implemented by test cases that require data from other test cases
template< class Obj >
class IDependent
{
public:

    void SetDependency( IDependency< Obj >* dependency )
    {
        dependency_ = dependency;
    };

protected:
    Obj GetDependency() const
    {
        return dependency_->Get();
    };

private:
    IDependency< Obj >* dependency_;
};

Two example test cases. One requires a const wchar_t object; one produces that object:

/// A test case that provides a "const wchar_t*" object to other test cases
class Foo : public ITest, 
            public IDependency< const wchar_t* >
{
public:
    const wchar_t* Get() 
    { 
        if( object_.length() == 0 )
            Execute();
        return object_.c_str();
    };

    virtual void Execute()
    {
        printf( "Execute Foo\n" );
        object_ = L"Object produced by Foo";
    };

private:
    std::wstring object_;
};

/// A test case that first requires a "const wchar_t*" object
class Bar : public ITest,
            public IDependent< const wchar_t* >
{
public:

    virtual void Execute()
    {
        const wchar_t* needed_object = GetDependency();

        printf( "Execute Bar with %S\n", needed_object );
    };
};

The test cases are stored in a list. Cases are added to the list by a registration process:

/// List of test cases to execute
std::vector< ITest* > list_;

/// Register a test case to execute with the system
void Register( ITest* test_case )
{
    list_.push_back( test_case );
}

Here’s my problem. I wanted to implement an overload of the ‘Register()’ function that also accepts dependencies. But, because dependencies can be of any type (not just the ‘const wchar_t*’ from this example), I’m not sure how to manage this. Below is an example of more or less what I’m looking for, but I’m not sure how to make it work.

/// Register a test case with dependencies with the system
void Register( ITest* test_case, ITest* dependency, ... )
{
    IDependent< ??? >* dependent = dynamic_cast< IDependent< ??? >* >( test_case );
    IDependency< ??? >* dep = dynamic_cast< IDependency< ??? >* >( dependency );

    va_list dep_list;
    for( va_start( dep_list, dependency ); 
         NULL != dep; 
         dep = dynamic_cast< IDependency< ??? >* >( va_arg( dep_list, ITest* ) ) )
    {
        dependent->SetDependency( dep );
    }
    va_end( dep_list );

    Register( test_case );
}

An example usage:

int _tmain( int argc, _TCHAR* argv[] )
{
    /// Test case Foo
    Foo foo;

    /// Test case bar (depends on Foo)
    Bar bar;

    /// Register test case Bar with a dependency on Foo
    Register( &bar, &foo );

    /// Execute Bar. Because it depends on Foo, that will be executed first
    list_->begin()->Execute();
    return 0;
}

Expected output:

Execute Foo
Execute Bar with Object produced by Foo

Does anybody have any suggestions on how I can successfully implement this architecture? (or a better architecture that actually works?)

Thanks,
PaulH

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-16T23:59:40+00:00Added an answer on May 16, 2026 at 11:59 pm

    I see two possible solutions.

    static

    Make the Register() method a template.
    The simple solution would be to limit the number of dependencies to some reasonable maximum.

    template <class T, class D1>
    void Register(T* test_case, IDependency<D1>* d1)
    {
        BOOST_STATIC_ASSERT(boost::is_base_and_derived<IDependent<D1>, T>::value);
        // since we now know that T is a IDependent<D1>, a dynamic_cast would only be necessary
        // to allow virtual inheritance.
        static_cast<IDependent<D1>*>(test_case)->SetDependency(d1);
        Register(test_case);
    }
    
    template <class T, class D1, class D2>
    void Register(T* test_case, IDependency<D1>* d1, IDependency<D2>* d2)
    {
        BOOST_STATIC_ASSERT(boost::is_base_and_derived<IDependent<D1>, T>::value);
        static_cast<IDependent<D1>*>(test_case)->SetDependency(d1);
        Register(test_case, d2);
    }
    
    template <class T, class D1, class D2, class D3>
    void Register(T* test_case, IDependency<D1>* d1, IDependency<D2>* d2, IDependency<D3>* d3)
    {
        BOOST_STATIC_ASSERT(boost::is_base_and_derived<IDependent<D1>, T>::value);
        static_cast<IDependent<D1>*>(test_case)->SetDependency(d1);
        Register(test_case, d2, d3);
    }
    
    // ...
    

    With compilers that support variadic templates this could probably be written in just one function template, for an unlimited amount of dependencies.

    Alternatively you could make Register() return a proxy-class, so that you could write something like this:

    Register(test_case)(dep1)(dep2)(dep3) /* ... */ (depN);
    

    The proxy class would store a pointer to the container and the test-case, and define a function-call-operator that looks just like the Register(T* test_case, IDependency* d1) function in the example above, only without the “test_case” argument and the final call to Register(test_case) (which one could do in the dtor of the proxy class).

    dynamic

    If I understand what you’re trying to do correctly, every “Dependency” can only produce one type of result.
    In that case you could modify the IDependency interface like this:

    class IDependencyBase
    {
    public:
        virtual void ApplyTo(ITest* target) = 0;
    };
    
    template <class T>
    class IDependency : public IDependencyBase
    {
    public:
        virtual void ApplyTo(ITest* target)
        {
            // cast to reference gives us an std::bad_cast if the types are not compatible,
            // which I think is a good thing here
            dynamic_cast<IDependancy<T>&>(*target).SetDependancy(this); 
        }
    
        virtual T Get() = 0;
    };
    
    template <class InputIterator>
    void Register(ITest* test_case, InputIterator begin, InputIterator end)
    {
        for (; begin != end; ++begin)
        {
            IDependancyBase* dep = *begin;
            dep->ApplyTo(test_case);
        }
        Register(test_case);
    }
    
    template <class Container>
    void Register(ITest* test_case, Container deps)
    {
        Register(test_case, deps.begin(), deps.end());
    }
    

    Now it might seem tempting to you to implement your varargs solution again, something like this (continuing from the second example):

    void Register(ITest* test_case, ...)
    {
        va_list dep_list;
        va_start(dep_list, test_case);
        while(IDependencyBase* dep = va_arg(dep_list, ITest*))
            dep->ApplyTo(test_case);
    
        va_end(dep_list);
    
        Register( test_case );
    }
    
    // and use it like
    
    int _tmain( int argc, _TCHAR* argv[] )
    {
        Foo foo;
        Bar bar;
    
        Register(&foo);
        Register(&bar, &foo, 0);
    
        list_->begin()->Execute();
        return 0;
    }
    

    However that isn’t guaranteed to work. In the code above, a Foo* is stored as a varagrs argument, and read back as a IDependencyBase*. That’s not guaranteed to work, since neither Foo nor IDependencyBase are PODs (IIRC they would both have to be PODs for this to be guaranteed to work — maybe it’s not guaranteed even then, I’d have to look it up in the standard). This is not some far fetched “not guaranteed by the standatd but will work everywhere” thing. Introduce multiple and/or virtual inheritance and this is almost guaranteed to fail.

    So general advice when using C++: don’t use varargs functions unless there is no other way. And there is always another way.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a small test application that executes two threads simultaneously. One increments a
I have an application that executes the following MySQL query: SELECT 402 AS user_id,
I have a ruby application that executes ant as a subprocess using backtick. This
I have a small shell application that embeds Tcl to execute some set of
I execute some tests within my application, but before doing that I have to
I have a Perl script that will execute three applications. All of it have
I'm writing a load-testing application in Java, and have a thread pool that executes
We have a (very) multithreaded application that would pass all unit tests, but would
I have a console application that utilizes the BackgroundWorker object and wanted to test
I have some test classes that are making use of spring-batch, and hibernate. My

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.