WAR*_*ead 2 c++ c++-concepts c++20 compiler-explorer
根据convertible_to中的 en.cppreference.com :
概念convertible_to<From, To>指定与std::declval()相同类型和值类别的表达式可以隐式和显式转换为To类型,并且两种转换形式是等效的。
我理解这意味着如果有成员,该convertible_to概念将被识别convertible_to<U, V>为满意。即使运算符是显式的而不是隐式运算符。Uexplicit operator V()
但是我发现msvc中不是这样的。
由于静态断言,以下代码无法编译:
#include <concepts>
#include <iostream>
class ExplictClass
{
public:
inline explicit operator int() const
{
return 5;
}
};
int main()
{
static_assert(std::convertible_to<ExplictClass, int>, "Explicit not convertible?"); // Fails here, concept not satisfied.
}
Run Code Online (Sandbox Code Playgroud)
这是我对概念的误解std::convertible_to,代码中的错误,还是 en.cppreference.com 中的错误,或者 msvc v19 的不一致性。
附上使用 x64 msvc v19.latest 的编译器资源管理器的链接,其中包含上述代码
编辑:
实际需要convertible_to是生成一个to_string函数模板,该模板可以与声明的可转换类型很好地配合,如下所示:
template<class T>
std::string to_string(T val)
{
std::ostringstream stream;
stream << val;
return stream.str();
}
template<Convertible<std::string> T>
std::string to_string(T val)
{
return static_cast<std::string>(val);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我希望像const char*,char*那样的类型,像ExplicitClass(with explicit operator std::string) all 这样的类型使用第二种方法,第一种方法是后备选项
std::convertible_to需要隐式和显式转换1)。这可以从定义中看出:
template <class From, class To>
concept convertible_to =
std::is_convertible_v<From, To> && // implicit conversion
requires { static_cast<To>(std::declval<From>()); }; // explicit conversion
Run Code Online (Sandbox Code Playgroud)
1) 注意:隐式可转换性几乎总是意味着显式可转换性
您ExplicitClass只有显式转换为int,这意味着您可以写入ExplicitClass(0),但不可能写入ExplicitClass e = 0;,这需要隐式转换。
ExplicitClass如果您想要一个测试是否可以显式转换为 的概念int,您有两个选择:
std::convertible_totemplate <class From, class To>
concept explicitly_convertible_to = requires {
static_cast<To>(std::declval<From>());
};
// assertion passes
static_assert(explicitly_convertible_to<ExplictClass, int>);
// constraint satisfied for T = ExplicitClass
template <explicitly_convertible_to<int> T>
int foo(T t);
Run Code Online (Sandbox Code Playgroud)
std::constructible_from// assertion passes
static_assert(std::constructible_from<int, From>);
// constraint satisfied for T = ExplicitClass
template <typename T>
requires std::constructible_from<int, T>
int foo(T t);
Run Code Online (Sandbox Code Playgroud)
请注意,std::constructible_from<To, From>将测试是否:
std::is_nothrow_destructible_v<To>, 和To obj(From)格式良好,是 的较弱形式static_cast<To>(From)(两者都是直接初始化,但只能static_cast向下转换指针从Base*to Derived*,以及其他差异)这意味着它std::constructible_from并不等同于 a static_cast,但它会完全按照您想要的类类型(如ExplicitClass.
| 归档时间: |
|
| 查看次数: |
274 次 |
| 最近记录: |