可能在 C++ 标准(C++17 或 C++20)中的概念。
所以我想知道这个新功能是否可以完全取代SFINAE,或者它只是一个带有很好的错误报告和类型检查的SFINAE的小版本。
是否有 SFINAE 是唯一选择而不是使用 Concepts 的情况?
有没有办法允许concept使用模板参数,可以使用提供的任何模板参数?
即模板参数占位符的某种通配符魔法?
\n一个使用示例:
\ntemplate<class Me, class TestAgainst>\nconcept derived_from_or_same_as = \n std::same_as<Me, TestAgainst> ||\n std::derived_from<Me, TestAgainst>;\nRun Code Online (Sandbox Code Playgroud)\n需要上面的内容是因为不幸的是,原始类型的 行为与和 的类类型不同。is_base_ofderived_from
现在我们可以定义一个Pair concept来检查提供的类型:
template<class P, class First, class Second>\nconcept Pair = requires(P p) {\n requires derived_from_or_same_as<decltype(p.first), First>;\n requires derived_from_or_same_as<decltype(p.second), Second>;\n};\nRun Code Online (Sandbox Code Playgroud)\n用例 [a] - 接受任何有效的As或As子类型对:
\n// this works well\nvoid doWithPairOfA(const Pair<A, A> auto& p) { /* */ }\nRun Code Online (Sandbox Code Playgroud)\n用例 …
此问题演示了如何使用 C++20 概念为函数模板选择重载。我正在尝试做一些类似的事情:为类模板选择专业化。
我从一个类模板开始,Angle<T>它包含一个包含弧度角的浮点值。使用概念,我可以确保用户不会Angle使用浮点类型以外的任何东西进行实例化:
template <std::floating_point T> struct Angle { T m_radians; };
Run Code Online (Sandbox Code Playgroud)
后来,我决定让客户使用Angle<T>可以处理整数类型的独特实现。换句话说,我想允许这样的代码:
const auto theta = Angle<float>(3.14f);
const auto phi = Angle<int>(180);
Run Code Online (Sandbox Code Playgroud)
所以我尝试添加一个可比较的模板。
template <std::integral T> struct Angle { T m_degrees; };
Run Code Online (Sandbox Code Playgroud)
编译器将此附加实现视为具有不同约束的模板的重新声明。我尝试了几种不同的方式来表达我的意图,但没有一种方法能满足我尝试过的任何编译器。事实上,我什至找不到用std::enable_if传统 SFINAE来做到这一点的方法——不可否认,我完全有可能不太了解 SFINAE。
我发现的唯一方法需要对每个整数和浮点类型进行不同的专门化。
template <std::floating_point T> struct AngleRad { T m_radians; };
template <std::integral T> struct AngleDeg { T m_degrees; };
template <typename T> struct Angle2 {};
template …Run Code Online (Sandbox Code Playgroud)