Search code examples
c++templatesc++-chronospecializationhigh-resolution-clock

How to write std::chrono::high_resolution clock class template specialization only if it is not alias


I want to write class template specializations for std::chrono::system_clock, std::chrono::steady_clock, and std::chrono::high_resolution_clock.

I wrote a straight forward code as follows:

#include <chrono>

template <typename T>
struct foo;

template <>
struct foo<std::chrono::system_clock> 
{};

template <>
struct foo<std::chrono::steady_clock> 
{};

// pseudo code    
//
// if constexpr (
//     !std::is_same_v(std::chrono::high_resolution_clock, std::chrono::system_clock> &&
//     !std::is_same_v(std::chrono::high_resolution_clock, std::chrono::steady_clock>
// ) {
// 

template <>
struct foo<std::chrono::high_resolution_clock> 
{};

// }

int main() {
}

Compile result: https://wandbox.org/permlink/8SqPZsMYdT8WKai3

If std::chrono::high_resolution_clock is an alias of std::chrono::system_clock or std::chrono::steady_clock, then I got the error redefinition of the same class template specialization.

I'm looking for a way to enable std::chrono::high_resolution_clock class template specialization only if it is not alias. I wrote comments (pseudo code) in the code that demonstrates what I want to do.

Is there any good way ?


Solution

  • You could provide an additional template parameter that depends on the condition you want to check. The primary template would be:

    template <typename T, bool = true>
    struct foo;
    

    and then the specialization would be:

    template <>
    struct foo<std::chrono::high_resolution_clock,
               !std::is_same_v<std::chrono::high_resolution_clock, 
                               std::chrono::system_clock>
               &&
               !std::is_same_v<std::chrono::high_resolution_clock, 
                               std::chrono::steady_clock>
              >
    {};
    

    Here's a demo.