我需要使用offsetof从template一个成员选择.如果您原谅尴尬的语法,我想出办法:
template <typename T,
typename R,
R T::*M
>
constexpr std::size_t offset_of()
{
return reinterpret_cast<std::size_t>(&(((T*)0)->*M));
};
Run Code Online (Sandbox Code Playgroud)
用法并不完美(最好烦恼):
struct S
{
int x;
int y;
};
static_assert(offset_of<S, int, &S::x>() == 0, "");
static_assert(offset_of<S, int, &S::y>() == sizeof(int), "");
Run Code Online (Sandbox Code Playgroud)
非constexpr形式更容易使用:
template <typename T, typename R>
std::size_t offset_of(R T::*M)
{
return reinterpret_cast<std::size_t>(&(((T*)0)->*M));
};
Run Code Online (Sandbox Code Playgroud)
明显的缺点是它不是在编译时完成的(但更容易使用):
int main()
{
std::cout << offset_of(&S::x) << std::endl;
std::cout << offset_of(&S::y) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找的是语法像非constexpr品种,但仍然完全编译时间; 但是,我无法想出它的语法.我也很满意offset_of<&S::x>::value(就像其他类型特征一样),但无法弄清楚它的语法魔法.
在C#中,如果你有struct这样的话:
struct Counter
{
private int _count;
public int Value
{
get { return _count; }
}
public int Increment()
{
return ++_count;
}
}
Run Code Online (Sandbox Code Playgroud)
你有一个这样的程序:
static readonly Counter counter = new Counter();
static void Main()
{
// print the new value from the increment function
Console.WriteLine(counter.Increment());
// print off the value stored in the item
Console.WriteLine(counter.Value);
}
Run Code Online (Sandbox Code Playgroud)
该计划的输出将是:
1
0
Run Code Online (Sandbox Code Playgroud)
这似乎完全错了.我要么期望输出为两个1(因为它Counter是a class或if struct Counter : ICounter和counter是ICounter)或者是编译错误.我意识到在编译时检测到这一点是一件相当困难的事情,但这种行为似乎违反了逻辑.
这种行为是否有理由超出实施难度?
我正在将一些代码移到GCC 4.7(从4.6)并遇到一些编译错误,并发现GCC 4.7移植指南中记录的问题:
用户定义的文字和空格
ISO C11模式下的C++编译器
std={c++11,c++0x,gnu++11,gnu++0x}支持用户定义的文字,这些文字与某些有效的ISO C++ 03代码不兼容.特别是,现在需要在字符串文字之后和可能是有效的用户定义文字之前的空格.获取有效的ISO C++ 03代码
Run Code Online (Sandbox Code Playgroud)const char *p = "foobar"__TIME__;在C++ 03中,TIME宏扩展为某个字符串文字,并与另一个字符串连接.在C++ 11
__TIME__中没有扩展,而是operator "" __TIME__被查找,导致以下诊断:Run Code Online (Sandbox Code Playgroud)error: unable to find string literal operator ‘operator"" __TIME__’这适用于某些宏后面没有空格的任何字符串文字.要修复,只需在字符串文字和宏名称之间添加一些空格.
虽然我可以修复错误,但我想知道为什么我必须这样做.__TIME__是一个宏,因此"something"__TIME__会"something""15:52:03"在预处理阶段变为(或类似),因此编译器永远不会有机会将其视为operator "".
这种行为是标准认可还是错误?
我有一些源对象src,想从中得到一个JValue.json4s的所有示例和文档似乎都围绕着获取JSON编码的字符串,如下所示:
def encodeJson(src: AnyRef): String = {
import org.json4s.NoTypeHints
import org.json4s.JsonDSL.WithDouble._
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization
import org.json4s.jackson.Serialization.write
implicit val formats = Serialization.formats(NoTypeHints)
write(src)
}
Run Code Online (Sandbox Code Playgroud)
如果我只想要最终结果,这很好,但我更愿意写一个:
def encodeJson(src: AnyRef): JValue
Run Code Online (Sandbox Code Playgroud)
这似乎ToJsonWritable[T]是我想要使用的,但我似乎无法找到一个实现Writer[AnyRef](也不能找到json4s的scaladocs,它只会告诉我实现).
我正在阅读我的STL实现(标准问题g++ 4.6.2),并在以下内容中遇到了这种竞争条件condition_variable:
template<typename _Rep, typename _Period>
cv_status
wait_for(unique_lock<mutex>& __lock,
const chrono::duration<_Rep, _Period>& __rtime)
{
return wait_until(__lock, __clock_t::now() + __rtime);
}
Run Code Online (Sandbox Code Playgroud)
因为__clock_t是一个std::chrono::system_clock,我们与NTP之类的东西有关(如果时钟在一天之后被移回__clock_t::now() + __rtime,那么我们将等待一天).
C++标准(30.5.1)看起来是正确的:
26
效果:好像
return wait_until(lock, chrono::steady_clock::now() + rel_time);
Boost的condition_variable实现有同样的问题:
template<typename duration_type>
bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration)
{
return timed_wait(m,get_system_time()+wait_duration);
}
Run Code Online (Sandbox Code Playgroud)
实际上,底层的pthreads实现似乎是问题所在:
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);
Run Code Online (Sandbox Code Playgroud)
因为abstime被指定为"系统时间",而不是单调时钟.
所以我的问题是:如何才能std::condition_variable::wait_for正确实现?是否有现成的实现可以做到这一点?或者我错过了什么?
我有一个类型特征系统驻留在命名空间中,如下所示:
namespace my_namespace
{
template <typename T>
struct magic_traits
{
static const int value = 0;
};
}
Run Code Online (Sandbox Code Playgroud)
因为人们讨厌模板特化的语法,所以我有这个方便的小宏:
#define DECLARE_MY_MAGIC_TRAITS(type_, value_) \
namespace my_namespace \
{ \
template <> \
struct magic_traits<type_ > { \
static const int value = value_; \
}; \
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是这只适用于在全局命名空间中进行的声明,因此某些其他命名空间中的类型的特征如下所示:
DECLARE_MAGIC_TRAITS(other_namespace::some_type, 9)
Run Code Online (Sandbox Code Playgroud)
如果人们知道所有关于哪里的小命名空间规则,那就太棒了DECLARE_MAGIC_TRAITS.如果他们没有并将声明放在他们自己的命名空间中,他们会得到如下错误:
'magic_traits' is not a template!
Specialization of non-template 'other_namespace::my_namespace::magic_traits'
Run Code Online (Sandbox Code Playgroud)
这对您图书馆的新用户来说非常困惑!
有没有办法让该宏能够magic_traits从任何地方定义专业化? 如果那是不可能的(我怀疑):可以使用哪些技术来生成更合理的错误消息?
我应该注意到我的用户大多是Python程序员,并且只有很少的C++经验,所以我可以做的任何事情都可以让他们的生活更轻松,更好.
我的命名空间ns中有一个函数可以帮助我打印STL容器.例如:
template <typename T>
std::ostream& operator<<(std::ostream& stream, const std::set<T>& set)
{
stream << "{";
bool first = true;
for (const T& item : set)
{
if (!first)
stream << ", ";
else
first = false;
stream << item;
}
stream << "}";
return stream;
}
Run Code Online (Sandbox Code Playgroud)
这适用于operator <<直接打印:
std::set<std::string> x = { "1", "2", "3", "4" };
std::cout << x << std::endl;
Run Code Online (Sandbox Code Playgroud)
但是,使用boost::format是不可能的:
std::set<std::string> x = { "1", "2", "3", "4" };
boost::format("%1%") % x; …Run Code Online (Sandbox Code Playgroud) 现在,我most用作寻呼机.虽然它为man页面提供了有用的语法高亮显示,但它缺少用于其他任何内容的彩色语法高亮显示(我特意寻找diff/C++).
同时,这pygments是一个很棒的节目.我可以用它轻松制作彩色输出:
# ./pygmentize -f console256 ${file}
hg diff | ./pygmentize -f console256 -l diff
Run Code Online (Sandbox Code Playgroud)
现在,我希望能够分页输出,所以我只使用:
# ./pygmentize -f console256 ${file} | most
hg diff | ./pygmentize -f console256 -l diff | most
Run Code Online (Sandbox Code Playgroud)
此时,大多数将所有着色控制字符转储到我的屏幕上,如下所示:
^[[38;5;28;01mclass^[[39;00m ^[[38;5;21;01mheap_allocator^[[39;00m
{
^[[38;5;28;01mpublic^[[39;00m^[[38;5;241m:^[[39m
Run Code Online (Sandbox Code Playgroud)
当然,这是不可读的.我查看了man页面most,但我找不到任何"嘿,显示那些控制字符作为颜色而不是打印它们"的选项. less具有相同的垃圾行为most,但more显示颜色完美,具有明显的存在限制more.
是否有一个寻呼机支持语法高亮或一些参数和程序的疯狂组合我可以串起来使这个工作?最后,我想从Mercurial得到差异和日志突出显示,所以也许有一个捷径...
我正在阅读Andrei Alexandrescu的The D Programming Language,并在拆卸序列中找到了这个金块:
... D假设退出应用程序将事实上释放与之关联的所有资源,因此它不会调用任何析构函数.
这对于内存资源很有用,但是网络套接字,自定义硬件,文件句柄等等呢?有没有办法保证我的析构函数总是被调用?另外:D是否提供了更好的方法来处理这些事情(我陷入了C++思维模式)?
一个演示问题:给定两个std::bitset<N>S,a并b检查是否有任何比特都设定a和b.
这个问题有两个相当明显的解决方案.这很糟糕,因为它会创建一个新的临时位集,并复制各种位置的值只是为了抛弃它们.
template <size_t N>
bool any_both_new_temp(const std::bitset<N>& a, const std::bitset<N>& b)
{
return (a & b).any();
}
Run Code Online (Sandbox Code Playgroud)
这个解决方案很糟糕,因为它一次只有一点,这不太理想:
template <size_t N>
bool any_both_bit_by_bit(const std::bitset<N>& a, const std::bitset<N>& b)
{
for (size_t i = 0; i < N; ++i)
if (a[i] && b[i])
return true;
return false;
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,我将能够做这样的事情,在这里block_type是uint32_t或任何类型bitset的存储:
template <size_t N>
bool any_both_by_block(const std::bitset<N>& a, const std::bitset<N>& b)
{
typedef std::bitset<N>::block_type block_type;
for …Run Code Online (Sandbox Code Playgroud) c++ ×6
type-traits ×2
bitvector ×1
boost ×1
boost-format ×1
c# ×1
c++11 ×1
command-line ×1
compilation ×1
d ×1
destructor ×1
gcc4.7 ×1
json4s ×1
namespaces ×1
offsetof ×1
pager ×1
readonly ×1
scala ×1
time ×1