gpt4 book ai didi

c++ - 如何防止std::is_constructible中的隐式转换

转载 作者:行者123 更新时间:2023-12-02 10:17:32 26 4
gpt4 key购买 nike

假设我有几个不同的类:

class constructible_from_float {
public:
constructible_from_float(float);
};
class constructible_from_double {
public:
constructible_from_double(double);
};
class constructible_from_long_double {
public:
constructible_from_long_double(long double);
};

然后,我想根据它们可构造的类型来做一些事情(简化示例):
#include <type_traits>
template <typename T>
constexpr size_t foo() {
if constexpr (std::is_constructible<T, float>::value) {
return 1;
} else if constexpr (std::is_constructible<T, double>::value) {
return 2;
} else if constexpr (std::is_constructible<T, long double>::value) {
return 3;
} else
return -1;
}

但是问题是,所有这些都返回 1:
[[maybe_unused]] auto float_result = foo<constructible_from_float>();
[[maybe_unused]] auto double_result = foo<constructible_from_double>();
[[maybe_unused]] auto long_double_result = foo<constructible_from_long_double>();

enter image description here

我知道该行为的原因是类型之间的隐式转换。
有没有一种合法的方法(至少可用于至少三种主要的编译器: msvcgccclang)来强制编译器区分这些类型。

我不允许更改类( constructible_from_float等),但可以做其他所有事情。
稳定版本的编译器提供的任何内容都是可以的(包括 c++2a)。

最佳答案

您必须愚弄C++编译器,以向您展示其要使用的隐式转换,然后使用SFINAE将其抛诸脑后,并且无法实例化模板,但无法实例化SFINAE,因此这不是错误。

#include <type_traits>
#include <iostream>

class constructible_from_float {
public:
constructible_from_float(float);
};
class constructible_from_double {
public:
constructible_from_double(double);
};
class constructible_from_long_double {
public:
constructible_from_long_double(long double);
};


template<typename T> class convertible_only_to {

public:
template<typename S, typename=std::enable_if_t<std::is_same_v<T,S>>>
operator S() const
{
return S{};
}
};


template <typename T>
constexpr int foo() {
if constexpr (std::is_constructible<T,
convertible_only_to<float>>::value) {
return 1;
} else
if constexpr (std::is_constructible<T,
convertible_only_to<double>>::value) {
return 2;
} else
if constexpr (std::is_constructible<T,
convertible_only_to<long double>>::value) {
return 3;
} else
return -1;
}

struct not_constructible_from_anything {};

int main()
{
std::cout << foo<constructible_from_float>() << std::endl;
std::cout << foo<constructible_from_double>() << std::endl;
std::cout << foo<constructible_from_long_double>() << std::endl;
std::cout << foo<not_constructible_from_anything>() << std::endl;

return 0;
}

关于c++ - 如何防止std::is_constructible中的隐式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61444125/

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