我是C++ 0x的新手,我试图绕过右值引用并移动构造函数.我正在使用带有-std = c ++ 0x的g ++ 4.4.6,我对以下代码感到困惑:
class Foo
{
public:
Foo()
: p( new int(0) )
{
printf("default ctor\n");
}
Foo( int i )
: p( new int(i) )
{
printf("int ctor\n");
}
~Foo()
{
delete p;
printf("destructor\n");
}
Foo( const Foo& other )
: p( new int( other.value() ) )
{
printf("copy ctor\n");
}
Foo( Foo&& other )
: p( other.p )
{
printf("move ctor\n");
other.p = NULL;
}
int value() const
{
return *p;
}
private: …Run Code Online (Sandbox Code Playgroud) 我有一个简单的类,它有一个 tostring() 方法:
class MyClass {
public:
std::string tostring() const;
static iterator begin();
static iterator end();
};
Run Code Online (Sandbox Code Playgroud)
虽然我现在正在使用 fmt 库,但这段代码是从没有的代码中移植过来的,所以许多遗留类都实现了 tostring() 方法,而且我有一个模板可以为任何类生成 fmt::formatter有那个方法 它一直运行良好。
然而,这个特殊的类也有开始/结束功能。但是,它们是静态的(此类类似于枚举,您可以遍历所有可能的值),并且与格式无关。
一切都很好,直到我需要为一些不同的代码包含 fmt/ranges.h。问题是有一个范围格式化程序可以看到开始/结束函数并希望将类格式化为范围。现在,如果我尝试格式化类,我会得到格式化程序的一个模棱两可的实例(一个用于我要使用的模板,一个用于范围格式化程序)。
有没有办法让范围格式化程序忽略这个类?
一个完整的例子是:
#include <type_traits>
#include <utility>
#include <string>
#include <vector>
#include <fmt/format.h>
// #include <fmt/ranges.h>
// Create formatter for any class that has a tostring() method
template <typename T>
struct has_tostring_member {
private:
template <typename U>
static std::true_type test( decltype(&U::tostring) );
template <typename U>
static std::false_type test(...);
public:
using result = decltype(test<T>(0) ); …Run Code Online (Sandbox Code Playgroud) 我正在使用g ++ 4.4在linux上编译共享库.如果我可以在库中,我想使用一些C++ 11功能,但我无法更新编译器的版本或需要为我的库用户使用任何特殊的编译器开关.
我有两个问题,我很难找到明确的答案.
如果我使用-std = c ++ 0x或-std = g ++ 0x编译共享库,我保证使用我的库的程序不需要那些开关(假设我没有c ++ 0x功能)头文件)?它似乎有效,但我不想在未来注册微妙的问题.
g ++ 4.4中C++ 11的标准库非常不完整.由于标准库的大部分都是标题库而且gnu的头文件通常都是版本ifdef,我认为可能有一种方法可以使用libstdc ++中至少头文件的更新版本.不过,我不能使用不同的.so.我相信我可以将它们整合在一起,但有可能正确地做这样的事情吗?
谢谢.
我有一些用户定义的迭代器,偶尔我会得到一个很容易解决的奇怪错误,但我不明白为什么我会得到它:
uint8_t bytes[pitch*height];
array_iterator::col_iterator a( &bytes[0] );
array_iterator::row_iterator base_iter_begin(
array_iterator::col_iterator( &bytes[0] ), width, pitch );
array_iterator::row_iterator base_iter_end(
array_iterator::col_iterator( &bytes[pitch*height] ), width, pitch
);
Run Code Online (Sandbox Code Playgroud)
我有一个名为array_iterator的类,嵌入了typedefs row_iterator和col_iterator.row_iterator构造函数将col_iterator作为其第一个参数.第一个和最后一个语句工作正常.中间语句无法编译,并出现以下错误:
test-2d-iterators.cc:780: error: declaration of 'bytes' as array of references
Run Code Online (Sandbox Code Playgroud)
写入&(字节[0])并不能解决问题(不出所料,因为[]的优先级高于&).当然,我可以用"a"代替显式col_iterator构造函数调用,但为什么我必须这样做?如果有问题,为什么最后一行中的col_iterator构造函数会编译?
谢谢.
我想声明如下:
class A {
std::unordered_set<A> set;
};
Run Code Online (Sandbox Code Playgroud)
我知道我需要 A 的哈希函数,但我认为这不是真正的问题。问题在于 unordered_set 的构造函数会犹豫,因为 A 是不完整类型。A 的前向声明并不能解决这个问题,但我不确定还有什么可能。
至于最小可重现的例子......
class A;
template <>
struct std::hash<A> {
// declare, but don't define, because A isn't defined yet
size_t operator()( const A& ) const;
};
class A {
public:
bool operator==( const A& ) const { return true; }
std::unordered_set<A> set;
};
inline size_t std::hash<A>::operator()( const A& ) const { return 0; }
Run Code Online (Sandbox Code Playgroud)
有什么办法可以做到这一点吗unordered_set<A*>?
使用 gcc 8.3.1 (C++14),我得到:
/usr/include/c++/8/ext/aligned_buffer.h: In instantiation of struct …Run Code Online (Sandbox Code Playgroud) 我有一些管理 unique_ptrs 队列的代码。在其主循环中,它从队列中弹出一个条目,对其执行某些操作,然后允许该元素超出范围并被删除。到目前为止,没有问题。
我想添加一个功能,我们可以将其移动到其他地方,而不是必须删除该元素。问题是只有元素本身知道是否执行此操作或它需要去哪里。
主循环类似于:
std::deque< std::unique_ptr<Object> > queue;
while( !queue.empty() ) {
auto element = std::move( queue.front() );
queue.pop_front();
element->do_something();
element->recycle( std::move(element) ); // ?
}
Run Code Online (Sandbox Code Playgroud)
如果回收不是对象的方法,这将不是问题,但因为它是对象的方法,我不确定它应该是什么样子。通过上面的代码,我会得到类似的东西:
class Object {
public:
virtual void do_something();
virtual void recycle( std::unique_ptr<Object> unique_this ) {
// move unique_this somewhere, or don't and allow it to be deleted
}
};
Run Code Online (Sandbox Code Playgroud)
这安全吗?如果recycle不移动unique_this,它将在它自己的方法之一中删除它(不过在方法的末尾)。那是问题吗?
我想到避免删除这个的一种可能性是让recycle通过左值引用获取unique_ptr,我意识到这有点奇怪。这个想法是,如果它愿意,它会将其移动到某个地方,但如果不这样做,则直到回收返回后该对象才会被删除。不过,它不一定避免在其方法之一中可能删除对象的问题,因为我们必须确保无论我们将其移动到何处都不会立即删除它。
如果这样做不安全,后备计划是让 Object 返回一个回收器(即,一个不是执行回收的 Object 方法的可调用对象)。我认为这应该是可能的,但是考虑到不同的对象想要使用不同的回收器,管理回收器的类型和生命周期会有点混乱。
在我看来,第一个想法(按值传递 unqiue_ptr)是最好的,除非它违反任何规则。这样安全吗?有一个更好的方法吗?