如果我定义了两个概念,并对每个概念都有一个类的部分特化,那么很明显,如果我有一个类型满足这两个概念,我就有一个二义性:
#include <cstdio>
template <typename T>
concept HasBar = requires {
typename T::Bar;
};
template <typename T>
concept HasBaz = requires {
typename T::Baz;
};
template <typename T>
struct Foo;
template <typename T> requires(HasBar<T>)
struct Foo<T> {
static void frobnicate() {
fprintf(stderr, "HasBar!\n");
}
};
template <typename T> requires(HasBaz<T>)
struct Foo<T> {
static void frobnicate() {
fprintf(stderr, "HasBaz!\n");
}
};
int main() {
struct MyFoo {
using Bar = int;
using Baz = float;
};
Foo<MyFoo>::frobnicate();
}
字符串
产量:
<source>:42:15: error: ambiguous partial specializations of 'Foo<MyFoo>'
42 | Foo<MyFoo> foo;
| ^
<source>:23:8: note: partial specialization matches [with T = MyFoo]
23 | struct Foo<T> {
| ^
<source>:30:8: note: partial specialization matches [with T = MyFoo]
30 | struct Foo<T> {
| ^
型
如果我从Foo
中删除Baz
类型,那么一切都会按照计划进行,它会打印HasBar!
当专门化像这样模糊不清时,我想手动指定一个优先级。我想我可以用一堆标签类型来做,较低的值代表较高的优先级:
#include <cstdio>
template <int N>
struct Priority : Priority<N-1> {};
template <>
struct Priority<0> {};
template <typename T>
concept HasBar = requires {
typename T::Bar;
};
template <typename T>
concept HasBaz = requires {
typename T::Baz;
};
template <typename T, typename Enabled = void>
struct Foo;
template <typename T> requires(HasBar<T>)
struct Foo<T, Priority<1>> {
static void frobnicate() {
fprintf(stderr, "HasBar!\n");
}
};
template <typename T> requires(HasBaz<T>)
struct Foo<T, Priority<0>> {
static void frobnicate() {
fprintf(stderr, "HasBaz!\n");
}
};
int main() {
struct MyFoo {
using Bar = int;
using Baz = float;
};
Foo<MyFoo>::frobnicate();
}
型
但这似乎只是完全排除了两个部分专业化:
<source>:42:4: error: implicit instantiation of undefined template 'Foo<MyFoo>'
42 | Foo<MyFoo>::frobnicate();
型
在新的C++20概念世界中应该如何做到这一点?
2条答案
按热度按时间mrfwxfqh1#
如果在这种情况下
Bar
应该具有优先级,则可以要求HasBaz<T>
的专门化也不具有Bar
:字符串
输出量:
型
如果从
MyFoo
中删除Bar
:型
输出量:
型
py49o6xq2#
你可以在函数重载中使用优先级:
字符串
Demo