考虑class A
满足两个概念ConceptA
和ConceptB
。让函数foo
为两个概念重载:
void foo(ConceptA& arg);
void foo(ConceptB& arg);
A a;
fun(concept_cast<ConceptA>(a));
注意:此示例使用“{Terse Notation”语法作为N3701的一部分提出,§5
是否存在类似concept_cast
的内容,允许用户选择重载?
例如:
让我们说
ConceptA
说T必须有一个成员函数bar()
ConceptB
说T必须有一个成员函数baz()
class A
同时拥有bar()
和baz()
成员函数
它明显含糊不清,但有没有办法明确选择我们static_cast
正常重载?
更新:已接受的答案超过2年。 c ++ 17中的任何更新?
答案 0 :(得分:4)
如果其中一个概念是另一个概念的约束版本(例如,满足ConceptA
的所有内容也将满足ConceptB
但反之亦然),那么{{{{{{{将选择1}}满足。
如果这两个概念都不比另一个更受约束,那么这两个概念被认为是模糊的重载。鉴于你如何处理这个问题,我希望你已经知道了这一点。
关于A
,我认为目前的提案中没有类似的内容。至少不是布里斯托尔会议(2013年4月)。我不认为这会改变,因为目前的重点似乎是确保概念 - 精简/约束提案的核心是可行的并且委员会可以接受。
可能需要明确选择这样的重载模板函数,也许这样的演员是正确的,但我不太确定。考虑到这样的强制转换仅对过载消歧很有用,其中concept_cast
是一个更通用的特性。 static_cast
的结果与重载决策上下文之外的原始值相同!
编辑:查看最新的提案(N3701),没有明确指定要实例化的模板函数的规定。
答案 1 :(得分:1)
您声称static_cast
可用于明确选择'正常'过载是一种似是而非的看法。可以在今天的C ++中编写以下内容:
template<typename P, EnableIf<NullablePointer<P>>...>
void foo(P&);
template<typename It, EnableIf<Iterator<It>>...>
void foo(It&);
假设NullablePointer
和Iterator
对相关的标准概念执行概念检查,那么int* q; foo(q);
没有编译的希望,因为int*
都是{{1}的模型和NullablePointer
(并且这两个概念都不包含另一个)。 Iterator
没有什么可以帮助解决这种情况。
我的示例(that you can test for yourself)非常相关,因为这种代码是Concepts Lite试图形式化的。您呈现的过载集等同于:
static_cast
请注意template<typename A>
requires ConceptA<A>
void foo(A& arg);
template<typename B>
requires ConceptB<B>
void foo(B& arg);
条款与requires
'条款之间的相似性。