使用 enable_if 为有符号和无符号变量创建可变参数构造函数
make a variadic constructor for signed and unsigned variables using enable_if
我想为 class 创建一个构造函数,使用任何整数类型,但区分有符号和无符号。我不希望它成为 class 本身的模板。以下不起作用。 Visual Studio 只是说没有参数匹配。
class Thing{
public:
template<typename Integral>
Thing(
typename std::enable_if<
std::is_integral<Integral>::value &&
!std::is_same<Integral,bool>::value &&
std::is_signed<Integral>::value
,Integral
>::type num
){
//constructor using signed variable as input
}
template<typename Integral>
Thing(
typename std::enable_if<
std::is_integral<Integral>::value &&
!std::is_same<Integral,bool>::value &&
!std::is_signed<Integral>::value//notice this is different
,Integral
>::type num
){
//constructor using unsigned variable as input
}
};
问题是该类型出现在 non-deduced context 中,因此编译器无法从类似 std::is_integral<Integral>::value
的内容中推断出它。试试这个:
#include <iostream>
#include <type_traits>
class Thing{
public:
template<typename Integral>
Thing(Integral num,
typename std::enable_if<
std::is_integral<Integral>::value &&
!std::is_same<Integral,bool>::value &&
std::is_signed<Integral>::value
,Integral
>::type* = nullptr
){
std::cout << "signed\n";
//constructor using signed variable as input
}
template<typename Integral>
Thing(Integral num,
typename std::enable_if<
std::is_integral<Integral>::value &&
!std::is_same<Integral,bool>::value &&
!std::is_signed<Integral>::value//notice this is different
,Integral
>::type* = nullptr
){
std::cout << "unsigned\n";
//constructor using unsigned variable as input
}
};
int main()
{
int x{};
unsigned int y{};
Thing thing1(x);
Thing thing2(y);
}
旁注:构造你的构造函数public
,否则你无法实例化你的对象。
我们需要将 SFINAE 移动到模板中。如果我们使用
class Thing{
public:
template<typename Integral, typename std::enable_if<
std::is_integral<Integral>::value &&
!std::is_same<Integral,bool>::value &&
std::is_signed<Integral>::value
,Integral>::type* = nullptr> // will fail if type does not exist
Thing(Integral i)
// ^ use Integral type here
{
std::cout << "signed\n";
}
template<typename Integral, typename std::enable_if<
std::is_integral<Integral>::value &&
!std::is_same<Integral,bool>::value &&
!std::is_signed<Integral>::value//notice this is different
,Integral>::type* = nullptr>
Thing(Integral i)
{
std::cout << "unsigned\n";
}
};
int main()
{
int a = 10;
Thing b(a);
unsigned int c = 10;
Thing d(c);
}
我们得到
signed
unsigned
我还必须使构造函数 public
默认为 private
。
我想为 class 创建一个构造函数,使用任何整数类型,但区分有符号和无符号。我不希望它成为 class 本身的模板。以下不起作用。 Visual Studio 只是说没有参数匹配。
class Thing{
public:
template<typename Integral>
Thing(
typename std::enable_if<
std::is_integral<Integral>::value &&
!std::is_same<Integral,bool>::value &&
std::is_signed<Integral>::value
,Integral
>::type num
){
//constructor using signed variable as input
}
template<typename Integral>
Thing(
typename std::enable_if<
std::is_integral<Integral>::value &&
!std::is_same<Integral,bool>::value &&
!std::is_signed<Integral>::value//notice this is different
,Integral
>::type num
){
//constructor using unsigned variable as input
}
};
问题是该类型出现在 non-deduced context 中,因此编译器无法从类似 std::is_integral<Integral>::value
的内容中推断出它。试试这个:
#include <iostream>
#include <type_traits>
class Thing{
public:
template<typename Integral>
Thing(Integral num,
typename std::enable_if<
std::is_integral<Integral>::value &&
!std::is_same<Integral,bool>::value &&
std::is_signed<Integral>::value
,Integral
>::type* = nullptr
){
std::cout << "signed\n";
//constructor using signed variable as input
}
template<typename Integral>
Thing(Integral num,
typename std::enable_if<
std::is_integral<Integral>::value &&
!std::is_same<Integral,bool>::value &&
!std::is_signed<Integral>::value//notice this is different
,Integral
>::type* = nullptr
){
std::cout << "unsigned\n";
//constructor using unsigned variable as input
}
};
int main()
{
int x{};
unsigned int y{};
Thing thing1(x);
Thing thing2(y);
}
旁注:构造你的构造函数public
,否则你无法实例化你的对象。
我们需要将 SFINAE 移动到模板中。如果我们使用
class Thing{
public:
template<typename Integral, typename std::enable_if<
std::is_integral<Integral>::value &&
!std::is_same<Integral,bool>::value &&
std::is_signed<Integral>::value
,Integral>::type* = nullptr> // will fail if type does not exist
Thing(Integral i)
// ^ use Integral type here
{
std::cout << "signed\n";
}
template<typename Integral, typename std::enable_if<
std::is_integral<Integral>::value &&
!std::is_same<Integral,bool>::value &&
!std::is_signed<Integral>::value//notice this is different
,Integral>::type* = nullptr>
Thing(Integral i)
{
std::cout << "unsigned\n";
}
};
int main()
{
int a = 10;
Thing b(a);
unsigned int c = 10;
Thing d(c);
}
我们得到
signed
unsigned
我还必须使构造函数 public
默认为 private
。