【发布时间】:2016-02-10 07:28:21
【问题描述】:
我正在创建自定义迭代器,但无法满足创建 const 迭代器并使用非const begin() 对其进行初始化的场景。根据 STL,这是合法的,可以用 std::string 来证明:
#include <string>
using namespace std;
int main() {
string::iterator a;
string::const_iterator b = a;
return 0;
}
我不知道如何使它工作:
template<typename T>
class some_class {
};
int main() {
some_class<int> a;
// Works OK!
const some_class<int> const_b = a;
// error: conversion from 'some_class<int>' to non-scalar type 'const some_class<const int>'
const some_class<const int> const_c = a;
return 0;
}
更新
@ALEXANDER KONSTANTINOV 提供了一个解决方案,但它不能满足所有可能的 STL 测试用例。接下来我正在测试@Bo Persson 的建议。将构造函数更改为 const some_class<U>& other 将允许它编译,但随后 iterator a = const_iterator b 也会错误地为真。
#include <string>
using namespace std;
template<typename T>
class some_class {
public:
some_class() {
}
template<typename U>
some_class(some_class<U>& other) {
}
};
namespace name {
typedef some_class<int> iterator;
typedef const some_class<const int> const_iterator;
}
int main() {
string::iterator a;
string::const_iterator b = a;
const string::iterator c;
string::iterator d = c;
string::const_iterator e = c;
name::iterator f;
name::const_iterator g = f;
const name::iterator h;
name::iterator i = h;
name::const_iterator j = h; // <- Error
return 0;
}
更新
在构造函数中添加const 似乎有些混乱。这是一个测试用例:
// This is not allowed by the STL
//string::const_iterator _a;
//string::iterator _b = _a; // <- Error!
// This should NOT compile!
name::const_iterator _a;
name::iterator _b = _a;
【问题讨论】:
-
你检查过标准库是如何实现的吗?
-
SFINAE 结合
std::remove_const和std::is_same让您有条件地提供合适的构造函数。 -
一种流行的方法是使
const_iterator成为iterator的基类。这样就存在从派生到基的隐式转换。 -
@Bo,您的建议似乎按预期工作,并完全回答了这个问题。我是否遗漏了任何警告或者这是否可靠?否则请作为答案提交。
标签: c++ stl constants std copy-constructor