gpt4 book ai didi

C++ 实现 is_convertible 和引用

转载 作者:行者123 更新时间:2023-11-28 05:44:57 26 4
gpt4 key购买 nike

我创建了以下特征模板类来确定是否可以将一种类型转换为另一种类型:

namespace Detail
{
struct IsConvertible
{
template <typename _Type, typename _OtherType>
static void convert(_OtherType);
template <typename _Type, typename _OtherType>
static auto test(_Type&&, _OtherType&&) -> decltype(convert<_Type, _OtherType>(std::declval<_Type>()), std::true_type());
static auto test(...) -> decltype(std::false_type());
};
}
template <typename _Type, typename _OtherType>
struct IsConvertible : public decltype(Detail::IsConvertible::test(std::declval<_Type>(), std::declval<_OtherType>()))
{};

然后尝试了以下测试用例:

void func1(int& i) {

}
void func2(int i) {

}
#include <iostream>
using namespace std;
int main()
{

cout << IsConvertible<int, long>::value;
cout << IsConvertible<int, float>::value;
cout << IsConvertible<int, int*>::value;
cout << IsConvertible<float, double>::value;
cout << IsConvertible<int&, int>::value;
cout << IsConvertible<int, int&>::value;

int i = 2;
int& ir = i;
int* ip = &i;

func1(i);
func2(ir);

return 0;
}

我使用的是 MSVC 2015。这些测试的输出是:

110110

它可以正确处理数字促销和转换,但在引用转换方面存在问题。这个实现有什么问题?

编辑:我更新了测试并将我的结果与 std::is_convertible 进行了比较。结果是一样的。

最佳答案

首先,你的问题有点不清楚。可以说,如果类型可以复制或移动构造,则“X &”可以转换为“X”;也可以说它们是不同的类型,不能转换。

鉴于您的一个测试用例导致 int 之间的“可转换”结果和一个 long ,我将假设您的预期结果是“松散的”。也就是说,如果有任何方法可以从 foo 进行转换至 bar ,那么结果是肯定的,您的问题在于:

cout << IsConvertible<int, int&>::value;

给出“false”的结果,但你期望:好吧,如果我有一个 int躺着,我应该可以把它变成一个 int & ,当然,没问题。

这是我的假设。那么,让我们看看这种转换在哪里偏离了轨道:

convert<_Type, _OtherType>(std::declval<_Type>()),

您在这里使用的是 SFINAE。 _Typeint . _OtherTypeint & .

顺便说一句,您不应该使用以下划线开头后跟大写字母的标识符。它们保留供 C++ 库使用。

你的 convert模板是:

template <typename _Type, typename _OtherType>
static void convert(_OtherType);

所以,对于这个模板实例化,你要实例化

static void convert(int &);

你的调用是:

convert(std::declval<int>());

std::declval<int>的实例化将返回一个 int,函数调用的结果为 std::declval<int> () 将是一个右值。

此函数调用失败,因为 int右值不能绑定(bind)到 int &函数调用参数,只给一个const int &范围。换句话说,有:

int declval();

void convert(int &);

以下失败:

convert(declval());

这就是您的 SFINAE 替换失败并且转换失败的原因。

我将建议一种稍微替代的方法:

template<typename Type> class TypeValue {

public:

static TypeValue param;
};

然后,而不是使用 std::declval ,使用这样的东西:

convert<_Type, _OtherType>(TypeValue<_Type>::param),

关于C++ 实现 is_convertible 和引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36415812/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com