小编ove*_*der的帖子

为什么链接器会在此模板中抱怨多个定义?

当包含在至少两个翻译单元(cpp文件)上时,这一小段代码会触发链接器的愤怒:

# ifndef MAXIMUM_HPP
# define MAXIMUM_HPP

template<typename T>
T maximum(const T & a, const T & b)
{
    return a > b ? a : b ;
}

/* dumb specialization */
template<>
int maximum(const int & a, const int & b)
{
    return a > b ? a : b ;
}

# endif // MAXIMUM_HPP
Run Code Online (Sandbox Code Playgroud)

但是用一个翻译单元编译和链接很好.如果我删除了专业化,它在所有情况下都能正常工作.这是链接器消息:

g++ -o test.exe Sources\test.o Sources\other_test.o
Sources\other_test.o:other_test.cpp:(.text+0x0): multiple definition of `int maximum<int>(int const&, int const&)'
Sources\test.o:test.cpp:(.text+0x14): first defined here
Run Code Online (Sandbox Code Playgroud)

模板是否允许多次实例化?如何解释此错误以及如何解决?

谢谢你的建议!

c++ templates template-specialization

15
推荐指数
2
解决办法
7899
查看次数

混合C和C++代码时确保异常传播的机制

我不是在问C++异常是否安全通过C代码传播,也不会在发生这种情况时发生什么.我已经在SO(阅读下面的问题1,2,3)和本FAQ.我问如何继续:

  • 避免将任何C++异常泄露给C代码(这意味着在调用C代码之前捕获C++域中的所有异常)
  • 还能够捕获C代码之外的异常(在更高的C++代码中).

让我说明一下我的想法:

Say libfoo是一个C库,我想在我的barC++程序中使用它.libfoo需要一个foo_callback我必须提供的回调函数.我的回调中使用的函数和方法可能抛出异常,所以我写道:

void my_callback(void)
{
    try
    {
        // Do processing here.
    }
    catch(...)
    {
        // Catch anything to prevent an exception reaching C code.
        // Fortunately, libfoo provides a foo_error function to
        // signal errors and stop processing.
        foo_error() ;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我使用我的回调,如下所示:

// The bar program.
int main()
{
    // Use libfoo function to set the desired callback
    foo_set_callback(&my_callback) ; …
Run Code Online (Sandbox Code Playgroud)

c c++ exception

8
推荐指数
1
解决办法
1794
查看次数

std :: for_each忽略默认函数参数

我偶然发现了一个奇怪的编译问题.我想使用处理字符串列表std::for_each.以下简化代码说明了问题:

# include <list>
# include <string>
# include <algorithm>

using namespace std ;

void f(wstring & str)
{
    // process str here
}

void g(wstring & str, int dummy = 0)
{
    // process str here, same as f, just added a second default dummy argument
}

int main(int, char*[])
{
    list<wstring> text ;

    text.push_back(L"foo") ;
    text.push_back(L"bar") ;

    for_each(text.begin(), text.end(), f) ;  // OK, fine :)
    for_each(text.begin(), text.end(), g) ;  // Compilation error, complains about 
                     // g …
Run Code Online (Sandbox Code Playgroud)

c++ boost std

7
推荐指数
1
解决办法
754
查看次数

这段代码是否包含隐藏的错误?

以下代码:

  • 使用gcc版本4.4.5(Ubuntu/Linaro 4.4.4-14ubuntu5/32bits)编译时运行正常
  • 使用MSVC10(Win7/32bits)编译时运行正常
  • 使用gcc版本4.5.2(Win7/32位上的MinGW)运行时崩溃

main.cpp:

# include <iostream>
# include <csetjmp>
# include <stdexcept>

using namespace std ;

void do_work(jmp_buf context)
{
    try
    {
        throw runtime_error("Ouch !") ;
    }
    catch(exception & e)
    {
    }

    longjmp(context, -1) ;                        //BP1
}

int main(int, char *[])
{
    jmp_buf context ;

    try
    {
        if( setjmp(context) != 0 )
        {
            throw runtime_error("Oops !") ;       //BP2
        }

        do_work(context) ;
    }
    catch(exception & e)
    {
        cout << "Caught an exception saying : " << e.what() …
Run Code Online (Sandbox Code Playgroud)

c++ mingw setjmp

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

如何移动元素而不删除并重新插入到boost :: multi_index_container中?

我正在使用boost :: multi_index_container来提供随机访问和对元素集合的基于散列的访问.我想更改元素的随机访问索引,而不更改基于哈希的索引.

这是一段代码:

# include <string>
# include <boost/multi_index_container.hpp>
# include <boost/multi_index/random_access_index.hpp>
# include <boost/multi_index/hashed_index.hpp>
# include <boost/multi_index/member.hpp>

using namespace std ;
using namespace boost ;
using namespace boost::multi_index ;

// class representing my elements
class Element
{
    public :
      Element(const string & new_key) : key(new_key) {}
      string key ;      // the hash-based index in the multi_index_container
      // ... many stuff skipped
    private :
      // ... many stuff skipped
} ;

typedef multi_index_container<
            Element,
            indexed_by<
                random_access< >, …
Run Code Online (Sandbox Code Playgroud)

c++ boost multi-index

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

如何在控制台程序中为DirectSound SetCooperativeLevel提供HWND?

我正在编写一个控制台程序,它使用DirectSound API来渲染一些音频数据.在按照DirectSound编程指南(来自Microsoft)时,我偶然发现了一个奇怪的问题.根据文件:

创建设备对象后,必须使用IDirectSound8 :: SetCooperativeLevel方法设置设备的协作级别.除非你这样做,否则不会听到任何声音.

问题是我正在编写一个控制台程序,并且SetCooperativeLevel需要HWND作为第一个参数.我没有在控制台程序中处理任何HWND.我尝试提供一个空指针,但它失败了一个DSERR_INVALIDPARAM错误代码.

应该IDirectSound8::SetCooperativeLevel在控制台程序中提供什么HWND值?计划的音频部分计划构建为共享库,因此几乎不知道"外部"程序.

谢谢你的建议!

注意:我知道有一个更好的解决方案可以简单地渲染音频,比如使用SDL,OpenAL,SFML(基于OpenAL),但对于我当前的项目,DirectSound是强制执行的.


编辑:我发现Microsoft工程师发来的消息消除了SetCooperativeLevel在创建GLOBAL_FOCUS缓冲区时使用桌面窗口或控制台窗口作为HWND的疑虑.

windows directsound

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

使用模板来克服缺少基类?

显然,标准容器没有公共基类,也没有通用接口,尽管方法名称是同构的.

问题:我必须用一组独特类型的对象填充容器.容器可以是a std::list,a std::vector或a std::deque,也可能是其他一些自定义容器.以下代码是最佳解决方案吗?

# include <string>
# include <iostream>
# include <list>
# include <vector>
# include <deque>

/*
 * Fill a container with two strings. The container
 * must expose the `clear` and `push_back` methods.
 */
template<typename T>
void f(T & t)
{
    t.clear() ;

    t.push_back("Alice") ;
    t.push_back("Bob") ;
}

int main(int, char*[])
{
    std::list<std::string>    l ;
    std::vector<std::string>  v ;
    std::deque<std::string>   q ;

    f(l) ;   // fill the list
    f(v) ;   // fill the …
Run Code Online (Sandbox Code Playgroud)

c++ templates std

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

包含 &lt;csetjmp&gt; 时,为什么 std 命名空间中没有 setjmp?

标题说明了一切。之后包括<csetjmp>,longjmpjmp_buf都在std命名空间中,但setjmp不是。我在 MinGW4.5 和 MSVC10 上验证了这一点。查看<csetjmp>标题后,我无法弄清楚这个选择的原因。我一直假设每个<cheader>文件都<header.h>std命名空间中包装 a 。

我错了吗 ?setjmp特殊情况背后的基本原理是什么?请赐教!

注意:我知道在 C++ 中滥用 setjmp/longjmp 的问题。

c++ std setjmp

3
推荐指数
1
解决办法
243
查看次数

要包含哪个标头才能使用std :: streamoff和std :: streamsize?

我想使用std::streamoffstd::streamsize类型而不会拉动iostream库的大部分内容.现在,我包括<iostream>标题.还有更好的方法吗?

c++ std

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