我正在使用新的explicit
来进行强制转换操作。如果你写了像
struct Data {
explicit operator string();
};
无法将Data
意外转换为string
。目标数据类型bool
是一个例外:在某些情况下,即使标记为explicit
- 上下文转换,也允许隐式转换。因此,您可以在if(...)
中使用此数据类型,例如:
struct Ok {
explicit operator bool(); // allowed in if(...) anyway
};
段落“25.4。(2)排序和相关操作”似乎允许<{>>标准容器的Compare
仿函数,如{{1}也是。但是我对gcc-4.7.0的尝试失败了,我注意到这是我的错误理解还是gcc中的错误?
set
在#include <set>
struct YesNo { // Return value type of Comperator
int val_;
explicit YesNo(int y) : val_{y} {}
/* explicit */ operator bool() { return val_!=0; }
};
static const YesNo yes{1};
static const YesNo no{0};
struct LessYesNo { // Comperator with special return values
YesNo operator()(int a, int b) const {
return a<b ? yes : no;
}
};
int main() {
std::set<int,LessYesNo> data {2,3,4,1,2};
}
之前没有explicit
示例编译。而我对“25.4。(2)”的理解是,这也应该用
我是否正确理解了Std,operator bool()
set
explicit
转换应该有效?这可能是gcc中的错误,或者是我明白了什么问题?
答案 0 :(得分:3)
我对标准的阅读有点不同 - 第25.4节涉及排序算法而不是排序容器;在25.4。(1)中建立的上下文意味着25.4。(2)中规定的比较对象的属性适用于25.4中的算法,而不是分类容器
1 25.4中的所有操作都有两个版本:一个需要a 比较类型的函数对象和使用运算符的函数对象。
2 Compare是一个函数对象类型(20.8)。的返回值 函数调用操作应用于Compare类型的对象,何时 上下文转换为bool(4),如果是第一个参数,则返回true 呼叫小于第二个,否则为假。比较comp 在整个过程中用于假设有序关系的算法。它是 假设comp不会通过的应用任何非常数函数 解除引用的迭代器。
我不知道你的例子是否有效,但我不认为第25.4节适用于此。
使用vector和std :: sort进行快速测试:
#include <list>
#include <algorithm>
struct YesNo { // Return value type of Comperator
int val_;
explicit YesNo(int y) : val_{y} {}
explicit operator bool() { return val_!=0; }
};
static const YesNo yes{1};
static const YesNo no{0};
struct LessYesNo { // Comperator with special return values
YesNo operator()(int a, int b) const {
return a<b ? yes : no;
}
};
int main() {
std::vector<int> data {2,3,4,1,2};
std::sort(std::begin(data), std::end(data), LessYesNo());
}
编辑:
关联容器的Compare参数是根据secion 25.4:
定义的1关联容器提供基于密钥的快速数据检索。该库提供了四种基本类型的关联容器:set,multiset,map和multimap。
2每个关联容器都在Key上进行参数化和排序关系比较 在Key的元素上引入严格的弱排序(25.4)。此外,map和multimap将任意类型T与Key相关联。 Compare类型的对象称为容器的比较对象。
和23.就我所看到的那样,在Compare的类型上没有其他条件,因此假设满足25.4约束的类型同样适用似乎是合理的。
答案 1 :(得分:2)
我是否正确理解了Std,对于set来说,明确的bool转换应该有效吗?
这是规范的灰色区域。比较函数的返回值必须是“可转换为bool”。但是根据explicit operator bool()
的含义还不清楚。
例如,可以将std::set
的比较用法写成:
CompFunc functor;
if(functor(input, currVal))
...
或者,可以这样做:
CompFunc functor;
bool test = functor(input, currVal);
if(test)
...
这两个技术在C ++ 11下都是合法的吗?不知道。显然,如果operator bool()
为explicit
,则第二个失败。
我查看了std::shared_ptr
的定义,它也有explicit operator bool()
。它还说std::shared_ptr
在第20.7.2.2节第2段中“可转换为布尔”。
所以我猜第二个版本应实现如下:
CompFunc functor;
bool test = static_cast<bool>(functor(input, currVal));
if(test)
...
事实上,规范中没有明确说明它意味着它应该作为缺陷报告提交。但它应该也可以作为GCC / libstdc ++ bug提交。
就个人而言,为了安全起见,我不会依赖它。
第4节第3段指出:
在这样的上下文中出现的表达式e被称为在上下文中被转换为bool并且当且仅当声明bool t(e)时才是格式良好的;对于一些发明的临时变量来说,这是一个良好的形式
因此“上下文可转换为bool”的操作意味着explicit operator bool()
将起作用。由于std::set
的“比较”函子必须符合25.4的要求,并且这些要求包括“上下文转换为bool”,它看起来像是GCC / libstdc ++错误。
但是,当你能提供帮助时,我仍然会避免这样做。