Can I overload functions with type-traits?

后端 未结 4 1518
南旧
南旧 2021-02-05 17:15

Let\'s say, I have six types, and they each belong in a conceptual category.
Here is a diagram that shows this:

<script

4条回答
  •  时光说笑
    2021-02-05 17:56

    I learned the following technique from R. Martinho Fernandes. The code shown below is written to illustrate the bare bones of the problem but you should refer to this blog post to get the full range of tricks to make it pretty.

    You've already mentioned that you're running into problems because of signatures being identical. The trick is to make the types to be different.

    Your second approach is close, but we can't use void as the resulting type of the std::enable_if<>.

    Note that the following code does not compile, and specifying void for the std::enable_if<> does not change anything since the default is void anyway.

    #include 
    
    class A {};
    class B {};
    
    template <
        typename T, 
        typename = typename std::enable_if::value>::type>
    void F(T) {
      std::cout << "A" << std::endl;
    }
    
    template <
        typename T, 
        typename = typename std::enable_if::value>::type>
    void F(T) {
      std::cout << "B" << std::endl;
    }
    
    int main() {
      F(A{});
      F(B{});
    }
    

    The reason, as you already described is because the signatures are identical. Let's differentiate them.

    #include 
    
    class A {};
    class B {};
    
    template <
        typename T,
        typename std::enable_if::value, int>::type = 0>
    void F(T) {
      std::cout << "A" << std::endl;
    }
    
    template <
        typename T, 
        typename std::enable_if::value, int>::type = 0>
    void F(T) {
      std::cout << "B" << std::endl;
    }
    
    int main() {
      F(A{});
      F(B{});
    }
    

    Prints:

    A
    B
    

    We have now differentiated the types between the 2 functions because rather than the second template parameter being a type, it is now an int.

    This approach is preferable to using std::enable_if<> in the return type for example since constructors don't have return types, the pattern wouldn't be applicable for those.

    Notes: std::is_same<> is used with a single class to simplify the condition.

提交回复
热议问题