小编Jar*_*edC的帖子

未定义的对静态const int的引用

我今天遇到了一个有趣的问题.考虑这个简单的例子:

template <typename T>
void foo(const T & a) { /* code */ }

// This would also fail
// void foo(const int & a) { /* code */ }

class Bar
{
public:
   static const int kConst = 1;
   void func()
   {
      foo(kConst);           // This is the important line
   }
};

int main()
{
   Bar b;
   b.func();
}
Run Code Online (Sandbox Code Playgroud)

编译时我收到一个错误:

Undefined reference to 'Bar::kConst'
Run Code Online (Sandbox Code Playgroud)

现在,我很确定这是因为static const int没有在任何地方定义,这是有意的,因为根据我的理解,编译器应该能够在编译时进行替换而不需要定义.但是,由于函数接受一个const int &参数,它似乎没有进行替换,而是更喜欢引用.我可以通过进行以下更改来解决此问题:

foo(static_cast<int>(kConst));
Run Code Online (Sandbox Code Playgroud)

我相信这现在迫使编译器创建一个临时的int,然后传递一个引用,它可以在编译时成功完成.

我想知道这是故意的,还是我期望从gcc中得到太多能够处理这种情况?或者这是我出于某种原因不应该做的事情?

c++ gcc

72
推荐指数
4
解决办法
3万
查看次数

处理模板中的void类型

我有一个模板化的函数,它调用另一个函数并存储它的返回值,然后在返回值之前做一些工作.我想扩展它来处理T = void,并想知道专业化是我唯一的选择.

template<typename T>
T Foo( T(*Func)() ) 
{
    // do something first (e.g. some setup)
    T result = Func();
    // do something after (e.g. some tear down)
    return result;
}

// Is this specialization the only option?
template<>
void Foo<void>( void(*Func)() ) 
{
    // do something first (e.g. some setup)
    Func();
    // do something after (e.g. some tear down)
    return;
}

void Bar() {}
int BarInt() { return 1; }

int main()
{
    Foo<int>(&BarInt);
    Foo<void>(&Bar);
} …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11

11
推荐指数
1
解决办法
4490
查看次数

中止HTTP/1.1块编码响应

是否有一种标准的方法来处理分块响应的响应失败?我已经倾注了RFC并且没有看到处理这个问题的标准方法.

我对分块响应的理解是,当我们无法在服务器上立即处理整个响应时,它们非常有用.因此,似乎有可能虽然通过处理响应的一部分方式发生致命错误并且响应需要终止.

我最初的想法是关闭连接是最好的解决方案,但我想确保没有其他方法来处理这种情况.谢谢.

http chunked-encoding

10
推荐指数
1
解决办法
866
查看次数

通过boost :: dynamic_bitset迭代

我有一个boost dynamic_bitset,我试图从中提取设置位:

boost::dynamic_bitset<unsigned long> myBitset(1000);
Run Code Online (Sandbox Code Playgroud)

我的第一个想法是在每个索引中执行一个简单的"转储"循环,并询问它是否已设置:

for(size_t index = 0 ; index < 1000 ; ++index)
{
   if(myBitset.test(index))
   {
      /* do something */
   }
}
Run Code Online (Sandbox Code Playgroud)

但后来我看到两个有趣的方法,find_first()并且find_next(),我认为肯定是意味着这个目的:

size_t index = myBitset.find_first();
while(index != boost::dynamic_bitset::npos)
{
        /* do something */
        index = myBitset.find_next(index);
}
Run Code Online (Sandbox Code Playgroud)

我运行了一些测试,看起来第二种方法效率更高,但这让我担心可能还有另一种"更正确"的方法来执行这种迭代.我无法在文档中找到任何示例或注释,指示迭代设置位的正确方法.

那么,使用find_first()find_next()迭代a的最佳方式dynamic_bitset,还是有另一种方式?

c++ boost

10
推荐指数
1
解决办法
4824
查看次数

限制用于mmap的缓冲区缓存

我有一个数据结构,我想重新按需页面输出. mmap似乎是运行一些初步实验的简单方法.但是,我想限制使用的缓冲区缓存量mmap.机器有足够的内存将整个数据结构分页到缓存中,但出于测试原因(以及一些生产原因),我不想让它这样做.

有没有办法限制使用的缓冲区缓存量mmap

或者,mmap可以实现类似但仍然限制内存使用的替代方案也可以.

c++ memory mmap

9
推荐指数
1
解决办法
911
查看次数

使用引用作为模板类型

在下面的示例中,Foo没有执行预期的操作,但我无法弄清楚为什么允许编译.

#include <string>
#include <iostream>

typedef std::string& T;

T Foo(int & i)
{
    return T(i);
}

int main()
{
    int a = 1;
    std::string & s = Foo(a);
}
Run Code Online (Sandbox Code Playgroud)

我用模板发现了这个,但typedef显示它与模板无关.不用说,s这里不是有效的字符串.我认为在返回中构造值Foo会产生编译错误.

我在这里错过了什么?

c++

7
推荐指数
2
解决办法
131
查看次数

朋友宣言没有向前宣布

我的理解是,friend如果使用了class说明符,声明也可以作为类的前向声明,如下例所示:

class A
{
    friend class B;
    B* b;
};

class B {};

int main() {}
Run Code Online (Sandbox Code Playgroud)

但是,g ++(4.6.3和4.7.0)给出了以下错误(g ++ - 4.7应该支持扩展好友声明),这是没有前向声明的预期:

main.cpp:6:2:错误:'B'没有命名类型

为了证实我friend class B;应该作为前瞻性声明的期望,我找到了这个答案这个答案,但两者都没有结论(或者至少我不能从中得出很多结论)所以我试图查阅c ++ 11标准,发现这个例子:

class X2 {
    friend Ct; // OK: class C is a friend
    friend D; // error: no type-name D in scope
    friend class D; // OK: elaborated-type-speci?er declares new class
}
Run Code Online (Sandbox Code Playgroud)

基于我对第三个声明的阅读,我friend class B应该是一个精心设计的类型说明符,声明一个新的类.

我刚刚开始理解官方的标准措辞,所以我必须遗漏一些东西.我有什么误会?

c++ c++11

7
推荐指数
2
解决办法
2678
查看次数

删除模板参数的g ++警告

我有一个简单的课程:

template<size_t N, typename T>
class Int
{
    bool valid(size_t index) { return index >= N; }
    T t;
}
Run Code Online (Sandbox Code Playgroud)

如果我将此类的实例定义为:

Int<0, Widget> zero;
Run Code Online (Sandbox Code Playgroud)

我得到一个g ++警告:

warning: comparison is always true due to limited range of data type
Run Code Online (Sandbox Code Playgroud)

我试图这样做,但我无法弄清楚如何使用非类型模板参数部分特化一个函数.看起来可能无法在g ++中禁用此警告.隐藏此警告或写入此方法的正确方法是什么,如果N == 0,它总是返回true?

谢谢!

c++ templates g++

6
推荐指数
1
解决办法
260
查看次数

通过make_shared停止堆分配

我想强制我的对象在堆栈上强制执行非常严格的语义并解决一些生命周期问题.我已经阅读了几篇关于如何做到这一点的文章,并开始operator new私有化(或删除).这似乎new直接使用时可以正常工作,但make_shared编译得很好.

#include <boost/smart_ptr.hpp>

class A
{
private:
   void *operator new( size_t );
   void operator delete( void* );
   void *operator new[]( size_t );
   void operator delete[]( void* );
};

int main()
{
//  A* a = new A;      // Correctly produces compile error
    boost::shared_ptr<A> a2 = boost::make_shared<A>();
}
Run Code Online (Sandbox Code Playgroud)

使用new A直接给我这个错误按预期:

error: ‘static void* A::operator new(size_t)’ is private
Run Code Online (Sandbox Code Playgroud)

我猜这make_shared是有效的,因为它正在使用placement new运算符,但我找不到任何讨论如何禁止这个的文章.我提出的最佳解决方案是明确删除模板专门化make_shared

namespace boost
{
    template<>
    shared_ptr<A> make_shared<A>() = delete;
};
Run Code Online (Sandbox Code Playgroud)

这显然是非常具体的 …

c++ c++11

6
推荐指数
1
解决办法
1088
查看次数

相邻内存区域的memcpy()安全性

我最近提出了一个关于使用volatile的问题,并被指示阅读英特尔和其他人讨论内存障碍及其用途的一些非常有用的文章.看完这些文章后,我变得非常偏执.

我有一台64位机器.从多个线程记忆到相邻的,非重叠的内存区域是否安全?例如,假设我有一个缓冲区:

char buff[10];
Run Code Online (Sandbox Code Playgroud)

一个线程是否总是安全地记忆到前5个字节,而第二个线程复制到最后5个字节?

我的直觉反应(和一些简单的测试)表明这是完全安全的,但我无法在任何可以完全说服我的文件中找到文档.

c++ multithreading memcpy

5
推荐指数
1
解决办法
1493
查看次数

标签 统计

c++ ×9

c++11 ×3

templates ×2

boost ×1

chunked-encoding ×1

g++ ×1

gcc ×1

http ×1

memcpy ×1

memory ×1

mmap ×1

multithreading ×1