Priority when choosing overloaded template functions in C++

后端 未结 6 432
不思量自难忘°
不思量自难忘° 2020-12-09 03:35

I have the following problem:

class Base
{
};

class Derived : public Base
{
};

class Different
{
};

class X
{
public:
  template 
  stat         


        
6条回答
  •  春和景丽
    2020-12-09 04:18

    I was looking to setup priorities on overlapping enable_if's, specifically for falling back on calling STL container methods, where my traits were things such as is_assignable is_insterable etc.. with which there is overlap on a number of containers.

    I wanted to prioritise assign, if it existed, else use an insert iterator. This is a generic example of what I came up with (modified with infinite levels of priority by some handy folk in the #boost irc channel). It works as the implicit conversion of the priority level ranks the overload below another that is otherwise an equally valid option - removing the ambiguity.

    #include 
    #include 
    
    template 
    struct priority : priority {};
    
    template <>
    struct priority<0> {};
    
    using priority_tag = priority<2>;
    
    template  
    void somefunc(T x, priority<0>)
    {
        std::cout << "Any" << std::endl;
    }
    
    template  
    std::enable_if_t::value >
    somefunc(T x, priority<2>)
    {
        std::cout << "is_pod" << std::endl;
    }
    
    template 
    std::enable_if_t::value >
    somefunc(T x, priority<1>)
    {
        std::cout << "is_float" << std::endl;
    }
    
    int main()
    {
        float x = 1;
        somefunc(x, priority_tag{});
        int y = 1;
        somefunc(y, priority_tag{}); 
        std::string z;
        somefunc(z, priority_tag{});
        return 0;
    }
    

    It was also suggested that in C++ 14 I could just use constexpr if statements to achieve the same thing, which was far cleaner if Visual Studio 2015 supported them. Hopefully this will help someone else.

    #include 
    #include 
    
    template 
    void somefunc(T x)
    {
        if constexpr(std::is_floating_point::value) {
          static_assert(std::is_floating_point::value);
          std::cout << "is_float" << std::endl;
        } else if constexpr(std::is_pod::value) {
          static_assert(std::is_pod::value);
          std::cout << "is_pod" << std::endl;
        } else {
          static_assert(!std::is_floating_point::value);
          static_assert(!std::is_pod::value);
          std::cout << "Any" << std::endl;
        }
    }
    
    int main()
    {
        float x = 1;
        somefunc(x);
        int y = 1;
        somefunc(y); 
        std::string z;
        somefunc(z);
        return 0;
    }
    

    // thanks to k-ballo @ #boost!

提交回复
热议问题