我一直想知道为什么你不能使用本地定义的类作为STL算法的谓词.
在问题:接近STL算法,lambda,本地类和其他方法,BubbaT提到" 由于C++标准禁止将本地类型用作参数 "
示例代码:
int main() {
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
std::vector<int> v( array, array+10 );
struct even : public std::unary_function<int,bool>
{
bool operator()( int x ) { return !( x % 2 ); }
};
std::remove_if( v.begin(), v.end(), even() ); // error
}
Run Code Online (Sandbox Code Playgroud)
有谁知道标准中的限制在哪里?禁止当地类型的理由是什么?
编辑:从C++ 11开始,使用本地类型作为模板参数是合法的.
当我在g ++ - 4.2中看到以下代码编译没有错误或警告时,我感到非常惊讶:
typedef enum test { one };
Run Code Online (Sandbox Code Playgroud)
我的假设是,如果您使用typedef
关键字,则需要额外的标识符,如:
typedef enum test { one } test;
Run Code Online (Sandbox Code Playgroud)
如前所述,g ++ - 4.2在没有警告的情况下接受它.Clang ++ 3.0警告" 警告:typedef需要一个名字 ",类似的Comeau警告" 警告:声明需要一个typedef名称 ",并且g ++ - 4.6通知:" 警告:'typedef'在此声明中被忽略 ".
我无法确定标准中允许的位置,并且我发现有两个编译器警告它是必需的,这有点令人困惑,如果typedef-name是必需的但不存在则不应该是错误吗?
更新:我用相同的编译器检查了C.Clang和comeau产生相同的输出,gcc发出警告:" 警告:空声明中无用的存储类说明符 ",这看起来更令人困惑.
更新:我已检查删除枚举的名称,结果是相同的:
typedef enum { one };
Run Code Online (Sandbox Code Playgroud)
与命名结构类似:
typedef struct named { int x };
Run Code Online (Sandbox Code Playgroud)
但是没有一个未命名的结构,在这种情况下,代码在g ++(4.2/4.6)中被拒绝" 错误:在typedef-declaration中缺少type-name ",gcc(4.2/4.6)发出警告:" warning:unnamed struct/union定义没有实例 ",clang ++" 警告:声明没有声明任何 ",comeau" 错误:声明需要typedef名称 "
我知道,之前的几个问题/答案已经很明确了,这volatile
与c ++内存模型的可见状态有关,而与多线程无关.
另一方面,Alexandrescu的这篇文章使用volatile
关键字not作为运行时特性,而是使用编译时检查来强制编译器无法接受可能不是线程安全的代码.在文章中,关键字的使用更像是required_thread_safety
标签,而不是实际的预期用途volatile
.
这(ab)使用volatile
合适吗?方法中可能隐藏了哪些可能的陷阱?
首先想到的是增加了混乱:volatile
与线程安全无关,但由于缺乏更好的工具,我可以接受它.
文章的基本简化:
如果声明一个变量volatile
,则只能volatile
在其上调用成员方法,因此编译器将阻止调用其他方法的代码.声明std::vector
实例volatile
将阻止该类的所有使用.添加一个执行const_cast
释放volatile
需求的锁定指针形状的包装器,将允许通过锁定指针进行任何访问.
窃取文章:
template <typename T>
class LockingPtr {
public:
// Constructors/destructors
LockingPtr(volatile T& obj, Mutex& mtx)
: pObj_(const_cast<T*>(&obj)), pMtx_(&mtx)
{ mtx.Lock(); }
~LockingPtr() { pMtx_->Unlock(); }
// Pointer behavior
T& operator*() { return *pObj_; }
T* operator->() { return pObj_; }
private:
T* pObj_;
Mutex* pMtx_;
LockingPtr(const LockingPtr&); …
Run Code Online (Sandbox Code Playgroud) 这就是重点.如何在其中写入和读取带有std :: vector的二进制文件?
我想的是:
//============ WRITING A VECTOR INTO A FILE ================
const int DIM = 6;
int array[DIM] = {1,2,3,4,5,6};
std::vector<int> myVector(array, array + DIM);
ofstream FILE(Path, ios::out | ofstream::binary);
FILE.write(reinterpret_cast<const char *>(&myVector), sizeof(vector) * 6);
//===========================================================
Run Code Online (Sandbox Code Playgroud)
但我不知道如何阅读这个载体.因为我认为以下是正确的,但它不是:
ifstream FILE(Path, ios::in | ifstream::binary);
FILE.read(reinterpret_cast<const char *>(&myVector), sizeof(vector) * 6);
Run Code Online (Sandbox Code Playgroud)
那么,如何进行操作?
在玩实现虚拟赋值运算符的过程中,我以一种有趣的行为结束了.它不是编译器故障,因为g ++ 4.1,4.3和VS 2005共享相同的行为.
基本上,虚拟运算符=与实际执行的代码相比,其行为与任何其他虚拟函数不同.
struct Base {
virtual Base& f( Base const & ) {
std::cout << "Base::f(Base const &)" << std::endl;
return *this;
}
virtual Base& operator=( Base const & ) {
std::cout << "Base::operator=(Base const &)" << std::endl;
return *this;
}
};
struct Derived : public Base {
virtual Base& f( Base const & ) {
std::cout << "Derived::f(Base const &)" << std::endl;
return *this;
}
virtual Base& operator=( Base const & ) {
std::cout << "Derived::operator=( …
Run Code Online (Sandbox Code Playgroud) 为什么调用erase
容器的成员函数const_iterator
失败?
它适用于非const iterator
.
此代码的行为与我的预期不符.
#include<iostream>
using namespace std;
class Class
{
Class()
{
cout<<"default constructor called";
}
~Class()
{
cout<<"destrutor called";
}
};
int main()
{
Class object();
}
Run Code Online (Sandbox Code Playgroud)
我期望输出'默认构造函数',但我没有看到任何输出.问题是什么?
我已经扩展了std :: string来满足我不得不将自定义函数构建编写到名为CustomString的字符串类中的需求
我已经定义了构造函数:
class CustomString : public std::string {
public:
explicit CustomString(void);
explicit CustomString(const std::string& str);
explicit CustomString(const CustomString& customString);
//assignment operator
CustomString& operator=(const CustomString& customString);
... };
Run Code Online (Sandbox Code Playgroud)
在第三个构造函数(复制构造函数)和赋值运算符中,其定义为:
CustomString::CustomString(const CustomString& customString):
std::string(static_cast<std::string>(customString))
{}
CustomString& CustomString::operator=(const CustomString& customString){
this->assign(static_cast<std::string>(customString));
return *this;
}
Run Code Online (Sandbox Code Playgroud)
首先,因为这是"明确的"; 意味着需要显式转换以分配给另一个CustomString对象; 它抱怨任务.
CustomString s = CustomString("test");
Run Code Online (Sandbox Code Playgroud)
我不确定在哪里确实需要铸造.
如果复制构造函数不是显式的,那么代码可以正常工作,但我想知道并实现显式定义而不是"猜测正确的强制转换".
两者之间是否存在功能差异:
void foo(const Bar& bar) {
Bar bar_copy(bar);
// Do stuff with bar_copy
}
Run Code Online (Sandbox Code Playgroud)
和
void foo(Bar bar) {
// Do stuff with bar
}
Run Code Online (Sandbox Code Playgroud)