繁体   English   中英

当模板函数也匹配时,如何定义一个特殊的句柄函数?

[英]How to define a special handle function when there is a template function also match?

我有一个带有模板函数和一个特殊函数的类,它看起来像:

#include <bits/stdc++.h>
using namespace std;

class A
{ 
 public:
  template <typename T>
  void test(const T& t) 
  {
    cout << "template " << t << endl;
  }

  void test(const std::string& s) {
    cout << "test " << s << endl;
  }
};

int main() 
{
  A a;
  a.test("asdas");
}

如您所见,有两个test功能:

  1. template函数
  2. 仅匹配std::string输入的特殊函数。

我想要的是:

  1. test(1) -> 调用template函数test<int>(1)
  2. std::string str = "asd"; test(str); -> 调用特殊函数test(str)
  3. test("asd") -> 调用特殊函数test(std::string str = "asd")

如何做到这一点?

asdas不是std::string ,而是可以称为const char*字符串文字 这就是为什么a.test("asd")没有调用成员void test(std::string const& s)


如何做到这一点?

一种解决方法是证明再增加一个成员超载

class A 
{
public:
    // ... code
    void test(std::string const& s) {
        cout << "test " << s << endl;
    }

    void test(const char* s) {   // overload for string literals
        test(std::string{s});
    }
};

查看演示

或者,在中,您可以SFINAE 这两个函数

class A
{
public:
    template <typename T>
    auto test(const T& t) // T can not be convertible to std::string
        -> typename std::enable_if<!std::is_convertible<T, std::string>::value>::type
    {
        std::cout << "template " << t << std::endl;
    }

    template<typename T>
    auto test(T const& s) // T can be convertible to std::string
        -> typename std::enable_if<std::is_convertible<T, std::string>::value>::type
    {
        std::cout << "test " << s << std::endl;
    }
};

查看演示


但是,如果您至少能够升级到 ,则可以使用字符串文字,并将std::string传递给void test(std::string const& s) (即不再需要成员重载)

using namespace std::string_literals;

a.test("asd"s);
//         ^^^

查看演示


更进一步,在中,我们可以使用if constexpr来决定在编译时要编译/丢弃的条件部分。

class A 
{
public:
    template <typename T>
    void test(const T& t)
    {
        if constexpr (!std::is_convertible_v<T, std::string>)
        {
            std::cout << "template " << t << std::endl;
        }
        else
        {
            std::cout << "test " << t << std::endl;
        }
    }
};

查看演示


另请阅读:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM