Library with Optional traits I am implementing a library in C/C++11 and I have chosen to follow Google C++ Style Guide as I also use this style guide in my code.

As such all classes and types (including typedefs and using) start with a capital letter.

However I have reached a conflict when implementing some traits.

For instance I have a RemoveOptional trait:

template &lt;class T&gt;
struct RemoveOptional {
  using Type = T;
};

template &lt;class T&gt;
struct RemoveOptional&lt;utils::Optional&lt;T&gt;&gt; {
  using Type = T;
};


that I can use like this:

utils::RemoveOptional&lt;utils::Optinal&lt;int&gt;&gt;::Type


But for the traits like IsXXX I have chosen to inherit std::true_type or std::false_type in order to be used like the std traits:

template &lt;class T&gt;
struct IsOptional : std::false_type {
};

template &lt;class T&gt;
struct IsOptional&lt;Optional&lt;T&gt;&gt; : std::true_type {
};


so this trait is used like this:

utils::IsOptional&lt;utils::Optional&lt;int&gt;&gt;::value
utils::IsOptional&lt;utils::Optional&lt;int&gt;&gt;::value_type


And value_type conflicts with my naming conventions as it should be ValueType.

As far as I see I have 3 options:


Modify all of my traits to follow the std convention.


Advantages: my traits can be checked against the std::true_type and std::false_type.
Disadvantages: my library is inconsistent.

Discard the std::true_type and std::false_type and make all my traits following my convention.


Advantages: my library is consistent.
Disadvantages: my traits can't be checked against std::true_type and std::false_type.

Leave as it is now.


Advantages: my traits can be checked against std::true_type and std::false_type.
Disadvantages: my library is inconsistent (even my traits are inconsistent between each other).



What should I do?
There is no single correct answer in all circumstances. You have to weigh the costs and benefits of the alternatives. Oddly enough my analysis seems to match yours, but here's one additional alternative you didn't explicitly cover:


Add redundant typedefs. All types you create will follow your standard, and those from the standard library will not. However you can easily provide aliases that expose parts of the standard library using names of your choosing. This is a little more code than the first option, and provides an opportunity for users of your class to use either name they like. If more than one name is used, the readability of the code can suffer. As such, while this initially may look like it combines the best of both extremes, in reality it also offers the worst.

template &lt;class T&gt;
struct IsOptional : std::false_type {
    using Type = std::false_type::value_type;
    using Value = std::false_type::value;
};

template &lt;class T&gt;
struct IsOptional&lt;Optional&lt;T&gt;&gt; : std::true_type {
    using Type = std::true_type::value_type;
    using Value = std::true_type::value;
};



However, once you're done writing the library, I would posit this is not all that important. I do not routinely use std::true_type or std::false_type when consuming a library. Template specialization is typically used to achieve two objectives at the same time:


Make the classes easy to use in flexible ways
Make the code that uses the classes really fast


Neither of these objectives really involve the consumers of the library having to care about the names of the types used in specializing its templates.

And thus my answer is this: don't sweat it. Do what makes you, and anyone else who is helping to implement your library, happy. This probably means choose the least amount of work, leaving you with mismatched conventions, but the ability to leverage knowledge of working with the standard library, but could mean writing your own TrueType and FalseType classes that follow your chosen naming conventions.