小编Ted*_*gmo的帖子

安全(且无成本)地重新解释大小数据

我想编写自己的“小向量”类型,第一个障碍是弄清楚如何实现堆栈存储。

我偶然发现了std::aligned_storage,它似乎是专门为实现任意堆栈存储而设计的,但我很不清楚什么是安全的,什么是不安全cppreference.com方便地提供了一个使用 的示例std::aligned_storage,我将在这里重复一下:

template<class T, std::size_t N>
class static_vector
{
    // properly aligned uninitialized storage for N T's
    typename std::aligned_storage<sizeof(T), alignof(T)>::type data[N];
    std::size_t m_size = 0;

public:
    // Create an object in aligned storage
    template<typename ...Args> void emplace_back(Args&&... args) 
    {
        if( m_size >= N ) // possible error handling
            throw std::bad_alloc{};

        // construct value in memory of aligned storage
        // using inplace operator new
        new(&data[m_size]) T(std::forward<Args>(args)...);
        ++m_size;
    }

    // Access an …
Run Code Online (Sandbox Code Playgroud)

c++ memory reinterpret-cast c++17 stdlaunder

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

为什么在 C++ 中 (0 &lt; 5 &lt; 2) 结果为真?

下面的代码std::cout << (0 < 5 < 2);输出1(true) 到控制台,即使从数学上讲,它5 < 2是假的。这背后的逻辑是什么?

假设:这是因为0 < 5计算为 1,因此0 < 5 < 2计算为1 < 2。我对么?

c++ math boolean-logic boolean

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

当混合成员和非成员二元运算符时,clang 是否错误地报告了歧义?

考虑以下代码,其中混合了成员和非成员operator|

template <typename T>
struct S
{
    template <typename U>
    void operator|(U)
    {}
};

template <typename T>
void operator|(S<T>,int) {} 

int main()
{
    S<int>() | 42;
}
Run Code Online (Sandbox Code Playgroud)

在 Clang 中,此代码无法编译,说明对的调用operator|不明确,而 gcc 和 msvc 可以编译它。我希望选择非成员超载,因为它更专业。标准规定的行为是什么?这是 Clang 中的错误吗?

(请注意,将运算符模板移到结构之外可以解决歧义。)

c++ operator-overloading clang language-lawyer clang++

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

使用隐藏可见性可以避免 ODR 违规吗?

例如,我的一个项目中有一个稍微复杂的库依赖情况:


              /--------------------------------\
              |                                |
      /----> GRPC <------------------\         |
      |                              |         |
      |        (c++)                 |         |        
      \-------   A  -------------->  B         |
                 |                 (rust)      |
                 |                             |
                 \------------------> c++  <---/ 
Run Code Online (Sandbox Code Playgroud)

Rust 默认情况下更喜欢使用静态链接。可执行文件 A 还构建为静态链接 lib(std)c++。因此,据我了解,A 和 B 中都会有两个 STL 实现副本。这正是https://developer.android.com/ndk/guides/cpp-support#sr建议避免的模式。

但是,查看nm -DB 的动态链接表(例如通过 );我看不到导出的 lib(std)c++/grpc 符号。这是因为 Rust 默认将它们标记为隐藏。

  • 那么,如果 B 中的所有公共符号都被隐藏,是否安全(或符合 ODR)?

c++ linker shared-libraries one-definition-rule rust

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

如果写小数点,还需要字母“f”吗?

下面两行代码有什么区别?

#define F_SAMP 10000.0f

#define F_SAMP 10000.0

两个不都浮起来吗?(顺便说一句,在这种特殊情况下,编译器是 XC16,但我认为这并不重要)感谢您的关注

c floating-point constants preprocessor-directive xc16

6
推荐指数
3
解决办法
518
查看次数

我可以限制 C++14 Vector 的大小吗?

正如图块所示,我是否可以在 C++ 14 中声明一个向量并限制它可以容纳的最大条目数?

c++ c++14

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

如何防止函数意外递归?

考虑以下 C++ 代码:

#include <iostream>

void get_val_from_db(const char* key, signed char& value)
{
    std::cout << "Getting value from db with signed char!\n";
}

void get_val_from_db(const char* key, unsigned char& value)
{
    std::cout << "Getting value from db with unsigned char!\n";
}

// overload to convert first argument from std::string to const char*
template <typename T>
void get_val_from_db(const std::string& key, T& value)
{
    get_val_from_db(key.c_str(), value);
}


int main()
{
    unsigned char my_value_unsigned = 0; // OK!
    get_val_from_db("my key", my_value_unsigned);

    signed char …
Run Code Online (Sandbox Code Playgroud)

c++ string templates c++17

6
推荐指数
2
解决办法
248
查看次数

使用 clang 显式 C++ 模板实例化

注意:几个相关问题(例如,这个问题)最终被标记为该问题的重复项。我知道这个特定问题并遵循相应答案中的解决方案。然而,不同的编译器会产生不同的行为,我不知道为什么。

我的库具有一个类模板,我想为库中的某些模板参数提供实例,因为该模板需要一些重要的编译时间。类模板可能如下所示 ( stack.hpp)

#ifndef MY_STACK
#define MY_STACK

template<class T>
class stack
{
public:
    stack();
};

#endif
Run Code Online (Sandbox Code Playgroud)

其实现驻留在相应的stack.tpp文件中

#ifndef MY_STACK_TPP
#define MY_STACK_TPP

#include <iostream>

template<class T>
stack<T>::stack()
{
    std::cout << "My stack constructor!" << std::endl;
}

#endif
Run Code Online (Sandbox Code Playgroud)

由于我只想提供对某些模板参数的支持,因此我stack.cpp创建了以下显式模板实例:

#include "stack.hpp"

template class stack<double>;
template class stack<char>;

#include "stack.tpp"
Run Code Online (Sandbox Code Playgroud)

它使用 g++ 和 clang++ 进行编译,但生成的共享库的符号存在差异:

g++ -std=c++11 -c stack.cpp -o stack.so
nm -C stack.so | grep stack
0000000000000049 t _GLOBAL__sub_I_stack.cpp
0000000000000000 W …
Run Code Online (Sandbox Code Playgroud)

c++ linker templates explicit-instantiation

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

使用 + 后接 ::(C++ 代码中的范围解析运算符

我有以下 C++ 代码片段:

inline std::vector<std::unique_ptr<xir::Tensor>> cloneTensorBuffer(
    const std::vector<const xir::Tensor*>& tensors)
{
    auto ret = std::vector<std::unique_ptr<xir::Tensor>>{};
    auto type = +::DataType::XINT;
    ret.reserve(tensors.size());
    for (const auto& tensor : tensors) {
        ret.push_back(std::unique_ptr<xir::Tensor>(xir::Tensor::create(
            tensor->get_name(), tensor->get_shape(), xir::DataType{type, 8u})));
    }
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

我对这个说法不太清楚:

auto type = +::DataType::XINT;
Run Code Online (Sandbox Code Playgroud)

+后面的::(范围解析运算符)是什么意思?

c++ scope-resolution-operator

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

在匿名联合成员的 lambda 表达式中捕获

众所周知,匿名联合是一个未命名的联合定义,它不会同时定义任何变量。匿名联合的成员被注入到封闭的范围内。但是在 lambda 表达式中捕获这些成员有什么限制吗?

在下面的示例程序中

int main() {
    union {
        int x{0};
        char y[4];
    };

    // error everywhere
    //[=]() { return x; };    
    //[&]() { return x; };

    // ok in GCC only
    [x]() { return x; };
    [&x]() { return x; };

    // ok in all
    [x=x]() { return x; };
    [&x=x]() { return x; };
}
Run Code Online (Sandbox Code Playgroud)

所有编译器都拒绝进行隐式捕获(通过值[=]和引用[&])。例如 Clang 的错误是

unnamed variable cannot be implicitly captured in a lambda expression
Run Code Online (Sandbox Code Playgroud)

至于显式捕获(通过值[x]和通过引用[&x] …

c++ lambda unions language-lawyer

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