我有一个包含std :: list的类,并希望为const_iterator提供public begin()和end(),为plain iterator提供private begin()和end().
但是,编译器看到私有版本并抱怨它是私有的而不是使用公共const版本.
我知道C++不会在返回类型(在本例中为const_iterator和iterator)上重载,因此它选择非const版本,因为我的对象不是const.
如果没有在调用begin()之前将我的对象转换为const,或者没有重载名称,那么有没有办法实现这一点?
我认为这是人们之前已经解决过的一种已知模式,并且希望如何解决这个问题.
class myObject {
public:
void doSomethingConst() const;
};
class myContainer {
public:
typedef std::list<myObject>::const_iterator const_iterator;
private:
typedef std::list<myObject>::iterator iterator;
public:
const_iterator begin() const { return _data.begin(); }
const_iterator end() const { return _data.end(); }
void reorder();
private:
iterator begin() { return _data.begin(); }
iterator end() { return _data.end(); }
private:
std::list<myObject> _data;
};
void myFunction(myContainer &container) {
myContainer::const_iterator itr = container.begin();
myContainer::const_iterator endItr = container.end();
for (; itr != endItr; …Run Code Online (Sandbox Code Playgroud) 作为我的计算机软件开发学位的一部分,我的一个实验室包括创建计算器类模板和分数类.
问题在于我的分数类.我的任务是重载加号运算符以允许将两个分数加在一起.
Fraction.cpp:
#include "Fraction.h"
const Fraction Fraction::operator+ (const Fraction &rhs) const
{
return Fraction(_num * rhs.GetDen() + (rhs.GetNum() * _den), _den * rhs.GetDen());
}
Run Code Online (Sandbox Code Playgroud)
Fraction.h
#pragma once
class Fraction
{
public:
Fraction(const int &num, const int &den) : _num(num), _den(den) {}
~Fraction(void) {}
const int GetNum(void) { return _num; }
const int GetDen(void) { return _den; }
const Fraction operator+ (const Fraction &rhs) const;
private:
const int _num, _den;
};
Run Code Online (Sandbox Code Playgroud)
Visual Studio抱怨我的分数访问器不能"将此指针从const分数转换为分数&".我完全不知所措.
这个问题很可能是"如何将字符串映射到枚举"的第n次迭代.
我的要求更进一步,throw当在有效输入范围内找不到密钥时,我想要一个例外.所以我有这个实现EnumMap(需要提升const std::map定义):
#include <map>
#include <string>
#include <sstream>
#include <stdexcept>
#include <boost/assign.hpp>
typedef enum colors {
RED,
GREEN,
} colors;
// boost::assign::map_list_of
const std::map<std::string,int> colorsMap = boost::assign::map_list_of
("red", RED)
("green", GREEN);
//-----------------------------------------------------------------------------
// wrapper for a map std::string --> enum
class EnumMap {
private:
std::map<std::string,int> m_map;
// print the map to a string
std::string toString() const {
std::string ostr;
for(auto x : m_map) {
ostr += x.first + ", ";
} …Run Code Online (Sandbox Code Playgroud) 以下测试程序返回不同的结果,具体取决于我使用的是libc ++还是libstdc ++.
#include <sstream>
#include <iostream>
int main()
{
int a = 0;
void* optr = &a;
void* iptr;
std::stringstream ss;
ss << optr;
std::cout << ss.str() << '\n';
ss >> iptr;
std::cout << iptr << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在OSX 10.9.2上使用Xcode 5的以下版本的clang
$ xcrun clang++ --version
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
Run Code Online (Sandbox Code Playgroud)
这是使用libstdc ++和libc ++构建时的测试输出
$ xcrun clang++ test.cpp <-- libstdc++ version
$ ./a.out
0x7fff5ec723e8
0x7fff5ec723e8
$ xcrun clang++ test.cpp …Run Code Online (Sandbox Code Playgroud) 长话短说,gcc和vc ++预处理器具有相同输入的不同输出.如果传递给另一个宏,vc ++中的变量宏似乎不会进行"参数匹配"(如果它是正确的术语).例如:
#define MACRO(a, ...) head:a, tail:MACRO_OTHER(__VA_ARGS__)
#define MACRO_OTHER(a, ...) head:a, tail:__VA_ARGS__
Run Code Online (Sandbox Code Playgroud)
同
MACRO(1, 2, 3, 4, 5)
Run Code Online (Sandbox Code Playgroud)
gcc输出:
head:1, tail:head:2, tail:3,4,5
Run Code Online (Sandbox Code Playgroud)
vc ++输出:
head:1, tail:head:2,3,4,5, tail:
Run Code Online (Sandbox Code Playgroud)
显然,a在MACRO_OTHER是2,3,4,5与空可变参数部分.考虑到这一点,有没有办法创建一个vc ++替代以下的宏(这与gcc很好)
#define VA_TYPES_WITH_ARGS(...) __VA_TYPES_WITH_ARGS(VA_NUM_ARGS(__VA_ARGS__),##__VA_ARGS__)
#define __VA_TYPES_WITH_ARGS(n, ...) _VA_TYPES_WITH_ARGS(n,##__VA_ARGS__)
#define _VA_TYPES_WITH_ARGS(n, ...) _VA_TYPES_WITH_ARGS_##n(__VA_ARGS__)
#define _VA_TYPES_WITH_ARGS_0()
#define _VA_TYPES_WITH_ARGS_1(type ) type _arg1
#define _VA_TYPES_WITH_ARGS_2(type, ...) type _arg2, _VA_TYPES_WITH_ARGS_1(__VA_ARGS__)
#define _VA_TYPES_WITH_ARGS_3(type, ...) type _arg3, _VA_TYPES_WITH_ARGS_2(__VA_ARGS__)
// etc
Run Code Online (Sandbox Code Playgroud)
它基本上附加_argK每个参数.
例:
VA_TYPES_WITH_ARGS(int, bool, float)
Run Code Online (Sandbox Code Playgroud)
将扩大到
int _arg3, bool _arg2, …Run Code Online (Sandbox Code Playgroud) 我有以下类定义:
class image {
public:
template <class T> image(int w, int h);
virtual ~image();
void clear();
};
template <class T> image::image(int w, int h) {
...
...
}
Run Code Online (Sandbox Code Playgroud)
构造函数在同一个头文件中定义.现在,我如何实例化这个类的对象?
我试过这个
image a<float>(128, 128);
Run Code Online (Sandbox Code Playgroud)
但得到以下错误
error: expected initializer before '<' token
image a<float>(128, 128);
Run Code Online (Sandbox Code Playgroud)
我该怎么做呢?
我有以下代码无法编译,抱怨+ =运算符不存在.+ =运算符在此处声明在A类之外.
template < typename _T >
class A {
public:
operator _T () const { return 42 ; }
};
template <typename _T >
A< _T > & operator += ( A< _T > & l, _T r ) { return l ; }
int main() {
A< int > e, f ;
e += f ;
return 0 ;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我在类A中实现运算符,代码编译并工作:
template < typename _T >
class A {
public:
operator _T () const { return 42 …Run Code Online (Sandbox Code Playgroud) 线索在标题中,但基本上我继承了一些有800多个strcpy实例的代码.我想编写一个新函数,然后用strcpy_mine替换strcpy.
所以我想弄清楚strcpy_mine将包含哪些参数列表.
我试过了:
void strcpy_mine( char* pTarget, const char* const pCopyMe )
{
const unsigned int lenAlwaysFour = sizeof(pCopyMe ); //:(
strncpy( pTarget, pCopyMe, lenAlwaysFour );
//add extra terminator in case of overrun
pTarget[lenAlwaysFour] = 0;
}
Run Code Online (Sandbox Code Playgroud)
但sizeof总是4 pCopyMe是一个指针
我不想做的就是更换
strcpy (buf, pCopyMe);
Run Code Online (Sandbox Code Playgroud)
同
strncpy (buf, pCopyMe, sizeof(pCopyMe)); buf[sizeof(pCopyMe)] = 0;
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?(strcpy_l不可用)
干杯
我正在使用预处理器宏来声明一些重复变量,具体来说:
QuitCallbackType quitCallback;
LossCallbackType lossCallback;
PauseCallbackType pauseCallback;
KeyCallbackType keyCallback;
MouseCallbackType mouseCallback;Run Code Online (Sandbox Code Playgroud)
我想使用预处理器宏来实现它,la
CREATE_CALLBACK_STORAGE(quit)
CREATE_CALLBACK_STORAGE(loss)
CREATE_CALLBACK_STORAGE(pause)
CREATE_CALLBACK_STORAGE(key)
CREATE_CALLBACK_STORAGE(mouse)
Run Code Online (Sandbox Code Playgroud)
它本质上是这样的:
#define CREATE_CALLBACK_STORAGE(x) capitalize(x)##CallbackType x##CallBack;Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点,所以我不必传递每个名称的大写和小写版本?
我意识到使用宏的打字并不多,但问题本身开始引起我的兴趣.
例如,
template<typename _RandomAccessIterator, typename _Compare>
inline void
sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType,
_ValueType>)
__glibcxx_requires_valid_range(__first, __last);
if (__first != __last)
{
std::__introsort_loop(__first, __last,
std::__lg(__last - __first) * 2, __comp);
std::__final_insertion_sort(__first, __last, __comp);
}
}
Run Code Online (Sandbox Code Playgroud)
由于这些模板放在命名空间std和大写,大写,小写和大写都使用,为什么需要前导下划线(单和双)?它只是那些开发人员的味道吗?还是有一些合理的技术原因?