如何在 C++ 中使用关键字 delete 删除特定的模板专业化
How to Delete specific template specialization with keyword delete in C++
我正在尝试了解 C++11 中关键字 delete 的一些用例。
所以我试图通过在 main 方法中删除其构造函数来删除特定的 class 模板特化。
这是我的代码:
using namespace std;
template <typename T>
class ComplexNumber
{
T x;
T y;
public:
ComplexNumber(T a, T b) : x(a) , y(b) {}
void display() { std::cout<<x << " + i"<<y<<std::endl; }
};
int main()
{
ComplexNumber(char a, char b) = delete;
ComplexNumber<int> obj1(1,2);
ComplexNumber<double> obj2(1.0,2.0);
ComplexNumber<char> obj3('1' , '2');
return 0;
}
但是程序执行并没有像预期的那样阻塞在 "ComplexNumber obj3('1' , '2')" 上,而是在 "ComplexNumber(char a, char b) = delete".
行上
这是错误的踪迹:
main.cpp: In function ‘int main()’:
main.cpp:28:18: error: missing template arguments before ‘(’ token
ComplexNumber(char a, char b) = delete;
^
main.cpp:28:19: error: expected primary-expression before ‘char’
ComplexNumber(char a, char b) = delete;
^~~~
main.cpp:28:27: error: expected primary-expression before ‘char’
ComplexNumber(char a, char b) = delete;
^~~~
main.cpp:28:43: error: expected primary-expression before ‘;’ token
ComplexNumber(char a, char b) = delete;
您能否帮助理解为什么我们不能在此处删除特定构造函数"for char type"?
对模板施加约束的更惯用的方法是使用 static_assert
.
#include <iostream>
using namespace std;
template <typename T>
class ComplexNumber
{
static_assert(!std::is_same_v<T, char>);
T x;
T y;
public:
ComplexNumber(T a, T b) : x(a) , y(b) {}
void display() { std::cout<<x << " + i"<<y<<std::endl; }
};
int main()
{
ComplexNumber<int> obj1(1,2);
ComplexNumber<double> obj2(1.0,2.0);
ComplexNumber<char> obj3('1' , '2');
return 0;
}
你想达到什么效果?
用户在尝试使用 char
实例化您的 class 时收到一条错误消息。在这里,我将使用带有有用消息的 static_assert
:
template <typename T>
class ComplexNumber
{
static_assert(!std::is_same_v<char, T>,
"char is not allowed because .... consider using ??? instead.");
// ...
};
当构造函数本身是一个函数模板时,通常你想要= delete
一个(或多个)构造函数:
class MyComplexNumber
{
double _re;
double _im;
public:
template <typename T>
MyComplexNumber(T re, T im) : _re(re), _im(im) { }
MyComplexNumber(char, char) = delete;
};
我想你是想这样做:
#include <iostream>
using namespace std;
template <typename T>
class ComplexNumber
{
T x;
T y;
public:
ComplexNumber(T a, T b) : x(a) , y(b) {}
void display() { std::cout<<x << " + i"<<y<<std::endl; }
};
template<> ComplexNumber<char>::ComplexNumber(char a, char b) = delete;//<== the right way to delete
int main()
{
ComplexNumber<int> obj1(1,2);
ComplexNumber<double> obj2(1.0,2.0);
ComplexNumber<char> obj3('1' , '2');
return 0;
}
最终会达到
main.cpp: In function ‘int main()’: main.cpp:19:39: error: use of deleted function ‘ComplexNumber::ComplexNumber(T, T) [with T = char]’
ComplexNumber<char> obj3('1' , '2');
^ main.cpp:13:12:
note: declared here template<> ComplexNumber<char>::ComplexNumber(char a, char b) = delete;
你可以测试一下here
我正在尝试了解 C++11 中关键字 delete 的一些用例。
所以我试图通过在 main 方法中删除其构造函数来删除特定的 class 模板特化。
这是我的代码:
using namespace std;
template <typename T>
class ComplexNumber
{
T x;
T y;
public:
ComplexNumber(T a, T b) : x(a) , y(b) {}
void display() { std::cout<<x << " + i"<<y<<std::endl; }
};
int main()
{
ComplexNumber(char a, char b) = delete;
ComplexNumber<int> obj1(1,2);
ComplexNumber<double> obj2(1.0,2.0);
ComplexNumber<char> obj3('1' , '2');
return 0;
}
但是程序执行并没有像预期的那样阻塞在 "ComplexNumber obj3('1' , '2')" 上,而是在 "ComplexNumber(char a, char b) = delete".
行上这是错误的踪迹:
main.cpp: In function ‘int main()’:
main.cpp:28:18: error: missing template arguments before ‘(’ token
ComplexNumber(char a, char b) = delete;
^
main.cpp:28:19: error: expected primary-expression before ‘char’
ComplexNumber(char a, char b) = delete;
^~~~
main.cpp:28:27: error: expected primary-expression before ‘char’
ComplexNumber(char a, char b) = delete;
^~~~
main.cpp:28:43: error: expected primary-expression before ‘;’ token
ComplexNumber(char a, char b) = delete;
您能否帮助理解为什么我们不能在此处删除特定构造函数"for char type"?
对模板施加约束的更惯用的方法是使用 static_assert
.
#include <iostream>
using namespace std;
template <typename T>
class ComplexNumber
{
static_assert(!std::is_same_v<T, char>);
T x;
T y;
public:
ComplexNumber(T a, T b) : x(a) , y(b) {}
void display() { std::cout<<x << " + i"<<y<<std::endl; }
};
int main()
{
ComplexNumber<int> obj1(1,2);
ComplexNumber<double> obj2(1.0,2.0);
ComplexNumber<char> obj3('1' , '2');
return 0;
}
你想达到什么效果?
用户在尝试使用 char
实例化您的 class 时收到一条错误消息。在这里,我将使用带有有用消息的 static_assert
:
template <typename T>
class ComplexNumber
{
static_assert(!std::is_same_v<char, T>,
"char is not allowed because .... consider using ??? instead.");
// ...
};
当构造函数本身是一个函数模板时,通常你想要= delete
一个(或多个)构造函数:
class MyComplexNumber
{
double _re;
double _im;
public:
template <typename T>
MyComplexNumber(T re, T im) : _re(re), _im(im) { }
MyComplexNumber(char, char) = delete;
};
我想你是想这样做:
#include <iostream>
using namespace std;
template <typename T>
class ComplexNumber
{
T x;
T y;
public:
ComplexNumber(T a, T b) : x(a) , y(b) {}
void display() { std::cout<<x << " + i"<<y<<std::endl; }
};
template<> ComplexNumber<char>::ComplexNumber(char a, char b) = delete;//<== the right way to delete
int main()
{
ComplexNumber<int> obj1(1,2);
ComplexNumber<double> obj2(1.0,2.0);
ComplexNumber<char> obj3('1' , '2');
return 0;
}
最终会达到
main.cpp: In function ‘int main()’: main.cpp:19:39: error: use of deleted function ‘ComplexNumber::ComplexNumber(T, T) [with T = char]’
ComplexNumber<char> obj3('1' , '2');
^ main.cpp:13:12:
note: declared here template<> ComplexNumber<char>::ComplexNumber(char a, char b) = delete;
你可以测试一下here