nic*_*ick 1 c++ templates class member-functions c++11
我有一个带有模板函数和一个特殊函数的类,如下所示:
#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");
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,有两个test函数:
template功能std::string。我想要的是:
test(1)-> 调用template函数test<int>(1)std::string str = "asd"; test(str);-> 调用特殊函数test(str)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});
}
};
Run Code Online (Sandbox Code Playgroud)
或者,在c++11中,您可以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;
}
};
Run Code Online (Sandbox Code Playgroud)
但是,如果您至少能够升级到c++14,则可以使用字符串文字,并将 传递std::string给void test(std::string const& s)(即不再需要成员重载)
using namespace std::string_literals;
a.test("asd"s);
// ^^^
Run Code Online (Sandbox Code Playgroud)
更进一步,在c++17中,我们可以使用 来决定在编译时编译/丢弃条件的哪一部分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;
}
}
};
Run Code Online (Sandbox Code Playgroud)
另请阅读:
| 归档时间: |
|
| 查看次数: |
111 次 |
| 最近记录: |