使用 C++ 模板定义函数,但显式删除它以防止误用
Use a C++ template to define a function but explicitly delete it to prevent misuse
我有一个带有构造函数的模板 class,我想在其中明确禁止使用定义明确的列表之外的任何类型,如下所示:
template<typename Anything>
class MyClass
{
public:
MyClass(int &);
MyClass(float &);
MyClass(Anything &) = delete;
}
但是,由于 integer 和 double 版本的代码相同,只是类型不同,我会喜欢使用模板化版本来定义它,例如:
template<typename Anything>
MyClass<Anything>::MyClass(Anything &var)
{
/* Code that operates over var */
...
}
而不是实际上必须为两个有效的构造函数复制代码。
但是,当我尝试这样做时,我得到:
error: redefinition of 'MyClass<Anything>::MyClass(Anything&)'
通过移除 "= delete".
有没有一种方法可以使用模板来定义函数,但又不明确允许接收比还明确描述的类型更多的类型?
我查了 and also ,但是他们的issue好像和现在的不一样
非常感谢。
更新:使用 gcc-4.8.5,它有效!!!即使包含 = delete 关键字。
您的定义存在问题,您正在尝试实现您用 = delete
标记的确切功能。
您实际上想要另一个同时适用于 int
和 float
的函数模板。您可以通过首先定义一个 IntOrFloat
谓词来实现:
template <typename T>
using IntOrFloat = std::bool_constant<
std::is_same_v<T, int> || std::is_same_v<T, float>>;
然后你可以定义两个使用 std::enable_if_t
的明确构造函数来检查用户传入的类型是否满足谓词:
class MyClass
{
public:
template <typename T,
std::enable_if_t<IntOrFloat<T>{}>* = nullptr>
MyClass(T&);
template <typename Anything,
std::enable_if_t<!IntOrFloat<Anything>{}>* = nullptr>
MyClass(Anything&) = delete;
};
用法示例:
int main()
{
int v0 = 0;
float v1 = 0.f;
const char* v2 = "igijsdg";
MyClass x0{v0}; // OK
MyClass x1{v1}; // OK
MyClass x2{v2}; // Error
}
我有一个带有构造函数的模板 class,我想在其中明确禁止使用定义明确的列表之外的任何类型,如下所示:
template<typename Anything>
class MyClass
{
public:
MyClass(int &);
MyClass(float &);
MyClass(Anything &) = delete;
}
但是,由于 integer 和 double 版本的代码相同,只是类型不同,我会喜欢使用模板化版本来定义它,例如:
template<typename Anything>
MyClass<Anything>::MyClass(Anything &var)
{
/* Code that operates over var */
...
}
而不是实际上必须为两个有效的构造函数复制代码。
但是,当我尝试这样做时,我得到:
error: redefinition of 'MyClass<Anything>::MyClass(Anything&)'
通过移除 "= delete".
有没有一种方法可以使用模板来定义函数,但又不明确允许接收比还明确描述的类型更多的类型?
我查了
非常感谢。
更新:使用 gcc-4.8.5,它有效!!!即使包含 = delete 关键字。
您的定义存在问题,您正在尝试实现您用 = delete
标记的确切功能。
您实际上想要另一个同时适用于 int
和 float
的函数模板。您可以通过首先定义一个 IntOrFloat
谓词来实现:
template <typename T>
using IntOrFloat = std::bool_constant<
std::is_same_v<T, int> || std::is_same_v<T, float>>;
然后你可以定义两个使用 std::enable_if_t
的明确构造函数来检查用户传入的类型是否满足谓词:
class MyClass
{
public:
template <typename T,
std::enable_if_t<IntOrFloat<T>{}>* = nullptr>
MyClass(T&);
template <typename Anything,
std::enable_if_t<!IntOrFloat<Anything>{}>* = nullptr>
MyClass(Anything&) = delete;
};
用法示例:
int main()
{
int v0 = 0;
float v1 = 0.f;
const char* v2 = "igijsdg";
MyClass x0{v0}; // OK
MyClass x1{v1}; // OK
MyClass x2{v2}; // Error
}