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 976443
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 16, 20262026-05-16T03:44:51+00:00 2026-05-16T03:44:51+00:00

I have a set of classes in a logging framework used by project A

  • 0

I have a set of classes in a logging framework used by project A and B. I am refactoring the framework so it can be used in project B and C. The refactoring mainly consists of giving everything template parameters: project A might run on an embedded device with poor/no STL implemenatation, while B and C just run on a pc, but B is single threaded while C uses multithreading.

This works well, but results in what seems to me an awfull lot of template parameters and a rather ugly typedef mess. I need like 20 lines to typedef all classes I’m going to use, and there are also lots of classes taking a template parameter they do not use themselves, but is needed to be able to typedef another class they do use (which is not per se a bad thing, but in the end everything starts to llok really complicated). Another problem is that when I want to add some functionality to class A and it requires adding a container, class A needs an extra template paramater. As a result, all other classes seeing/using class A suddenly also need that extra parameter leading to a domino effect.

Slightly exaggerated example:

template< class string, class map, class mutex >
class MessageDestination
{
  typedef Message< string, map > message_type;
  virtual void Eat( const message_type& ) = 0;
}

template< class string, class map, class stream >
class MessageFormatter
{
  typedef Message< string, map > message_type;
  virtual void Format( const message_type&, stream& ) = 0;
}

template< class string, class map, class containerA,
          template< class, class > containerB, template< class, class > class queue, class allocator >
class ThreadedMessageAcceptor
{
  typedef Message< string, map > message_type;
  typedef MessageDestination< string, map > destination_type;
  typedef containerB< destination_type, allocator > destinations_type;
  typedef queue< message_type, allocator > messages_type;
};

I can think of some techniques to clean this up, but I’m having a hard time deciding what one or which combination to use. StackOverFlow, your help will be appreciated!

Here’s the first solution I thought of, joining parameters together into the type they’ll eventually form:

template< class message, class mutex >
class MessageDestination
{
  virtual void Eat( const message& ) = 0;
}

This makes it simpler, but doesn’t it at the same time it kind of hides what message actually is? Suppose a user wants to provide an implementation, he does not directly see that message has to use a certain string type etc.

Another technique I thougt about, but cannot recall having seen before somwhere which makes it look suspicious, is simply defining everything in a single struct and passing that as single template parameter to everything:

struct MyTemplateParameters
{
  typedef std::string string;
  typedef std::map map;
  typedef std::queue queue;
  typedef LightMutex mutex;
  template< class A, class B >
  struct DefineContainerB
  {
    typedef containerB< A, B >::type;
  }
  //....
};

template< class parameters >
class MessageDestination
{
  typedef Message< parameters > message_type;
  virtual void Eat( const message_type& ) = 0;
};

template< class parameters >
class ThreadedMessageAcceptor
{
  typedef Message< parameters > message_type;
  typedef MessageDestination< parameters > destination_type;
  typedef parameters::DefineContainerB< destination_type, parameters::allocator >::type destinations_type;
};

This is nice as it allows specifying everything at one single point, and the typedefs to all classes will all be class XXX< MyTemplateParameters >, but again, it gives me an uneasy feeling. Is there a reason for this?

  • 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-16T03:44:52+00:00Added an answer on May 16, 2026 at 3:44 am

    The “other” technique is very common in C++. The parameters class is usually called a “trait class”.

    This is the way to go (why does it give you an uneasy feeling?). It is used pervasively in the Boost libraries and other C++ libraries. Even the standard library uses it, e.g. in the std::basic_string class.


    An equally well-established alternative are metafunctions. At its most basic, a metafunction is a “function” that operates on types rather than objects. So where a function takes value arguments and returns a value, a metafunctions takes template arguments and “returns” a type:

    template <typename T>
    struct identity {
        typedef T type;
    };
    

    The metafunction is used (“invoked”) like a normal type definition.

    typedef identity<int>::type mytype; // or
    identity<int>::type x;
    

    Not very useful in this case. But consider the following common metafunction:

    template <typename T>
    struct remove_const {
        typedef T type;
    };
    
    template <typename T>
    struct remove_const<T const> {
        typedef T type;
    };
    

    This can be used to make an arbitrary type (in particular a template argument) non-const. This is actually a type I’m currently using in a project: I have a class that accepts both const and non-const types and offers appropriate interfaces. However, internally I need to store a non-const reference. Simple, I just use the following code in my class:

    typename remove_const<T>::type& _reference;
    

    (The typename is required because T is a template argument and that makes remove_const<T>::type a dependent type. Your above example code is actually omitting quite a few required typenames – it won’t compile on several modern compilers!)

    Now, how to apply this to your problem?

    Create two empty marker types that specify whether your types are used on an embedded device or on a compliant compiler:

    struct Embedded { };
    struct Compliant { };
    

    Now you can define your classes in terms of these, e.g.:

    template<typename Spec>
    class ThreadedMessageAcceptor
    {
        typedef Message< Spec > message_type;
        typedef MessageDestination< Spec > destination_type;
        typedef typename Allocator< destination_type, Spec >::type allocator_type;
        typedef typename ContainerB< destination_type, allocator_type, Spec >::type destinations_type;
    };
    

    Here, Spec will be either Compliant or Embedded. So to use it on a standards compliant compiler, write:

    ThreadedMessageAcceptor<Compliant> x;
    

    The class uses the following metafunctions:

    template <typename T, typename Spec>
    struct Allocator { };
    
    template <typename T, typename Alloc, typename Spec>
    struct ContainerB { };
    

    You need to remember to specialize them appropriately for your target specifications, e.g.:

    template <typename T>
    struct Allocator<T, Compliant> {
       typedef std::allocator<T> type;
    };
    
    template <typename T, typename Alloc>
    struct ContainerB<T, Alloc, Compliant> {
        typedef std::vector<T, Alloc> type;
    };
    

    This already shows that a metafunction may have arbitrarily many arguments besides the Spec (which I’ve put last on a whim – but its placement should be consistent).

    To be sure, this is more code than when using a single trait class but it has lower cohesion, logically separates concerns and is easier to reuse.

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

Sidebar

Related Questions

I have a project with a set of classes that are responsible for their
I have a NetBeans project set up with a bunch of source classes and
Present Scenario : I have a set of classes that all take a common
I have a requirement where in i have a set of classes and they
I'm using ASP.NET MVC RC2. I have a set of classes that were auto-generated
I have two classes set up as follows: class Point { protected: double coords[3];
I have written a set of classes and interfaces that are implemented in Moose
I am using Hibernate to do mapping. One of my classes have a set
I have classes which have automatic properties only like public customerName {get; set;}. They
I have two classes: public class MultilingualString { public int Id { get; set;

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.