'Using "typedef" or "using" to define a structure - which is best?

Sample structure:

typedef struct tagExportSettings
{
    COLORREF    crHeading{};
    COLORREF    crEvenBack{};
    COLORREF    crOddBack{};
    COLORREF    crHighlight{};
    COLORREF    crDate{};
    COLORREF    crEvent{};
    COLORREF    crEmpty{};
    COLORREF    crNotes{};

} EXPORT_SETTINGS_S;

Visual Assist says:

typedef can be converted to using declaration.

Is there any real benefit of making this code change?

All my code in the software uses EXPORT_SETTINGS_S so I don't want to break that syntax.



Solution 1:[1]

Even better is to use neither. One type name should be enough. Pick either tagExportSettings or EXPORT_SETTINGS_S and stick with it. Example:

struct tagExportSettings
{
    // ...
};

But, 1. All my code in the software uses EXPORT_SETTINGS_S

As I said, pick either name. If you use EXPORT_SETTINGS_S, then name the class as EXPORT_SETTINGS_S:

struct EXPORT_SETTINGS_S
{
    // ...
};

If something still refers to tagExportSettings, then refactor the code to use the canonical name.


But more generally, using is preferred to typedef because it's more readable. There are at least two reasons for it:

  1. With typedef syntax it isn't intuitive which is the old name and which is the new alias:

    typedef new_or_old old_or_new; // old_or_new is the new alias
    

    using is intuitive through familiar pattern of initialisation:

    using intuitively_alias = intuitively_old_name;
    
  2. typedef syntax is difficult for a programmer to parse in case of compound names because the alias is "interleaved":

    // alias for void()
    typedef void function();
    using function = void();
    

Solution 2:[2]

If you are writing in C++, using is much better. For example, a template struct like this:

template <typename Tp>
struct WrapData
{
    const bool has_value = !std::is_void<Tp>::value;
    typename std::conditional<std::is_void<Tp>::value, uint8_t, Tp>::type value;
    // more properties
};

You can use typedef or using like this:

using void_t = WrapData<void>;
using int_t = WrapData<int>;

// same as using
typedef WrapData<int> tp_int_t;

But only using can work if use template:


// // compile error
// template<typename Tp>
// typedef WrapData<Tp> TpWrapData;

template<typename Tp>
using UsWrapData = WrapData<Tp>;

Solution 3:[3]

Assuming pure C++, it depends if you're using raw pointers or not. If you don't, then just define the struct under proper name without either typedef or using.

struct EXPORT_SETTINGS_S
    {...

If you're using raw pointers a lot and in Windows, it's customary to define not just alias but a pointer type as well:

typedef struct tagExportSettings
{
    ...
} EXPORT_SETTINGS_S, *LPEXPORT_SETTINGS_S;

That certainly matters only if you are accustomed to LPXXX "types". If you're a * person, then there's no need.

Neither of those are a clear-cut case for using.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3