小编Fra*_*ler的帖子

C++对象构造方法的区别

C++中不同的构造语法总是让我感到困惑.在另一个问题中,有人建议尝试初始化一个字符串

std::string foo{ '\0' };
Run Code Online (Sandbox Code Playgroud)

这有效并产生预期结果:长度为1的字符串仅包含空字符.在测试代​​码时,我不小心输入了

std::string foo('\0');
Run Code Online (Sandbox Code Playgroud)

这编译很好(即使没有警告-Wall),但在运行时终止

terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_M_construct null not valid
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

现在,据我所知,没有构造std::string接受一个字符作为参数,而这一假设是进一步证实了,当我试图通过间接的角色.

char b = '\0';
std::string a(b);
Run Code Online (Sandbox Code Playgroud)

这会产生一个很好的,冗长的编译错误.就像这样

std::string a('z');
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:什么允许std::string a('\0');编译,以及它与什么不同std::string a{ '\0' };


脚注:g++在Ubuntu上进行编译.这并没有把我当作编译器错误,但以防万一......

c++ string constructor c++11

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

为什么使用 __LINE__ 的这段代码在发布模式下在 MSVC 下编译,而不是在调试模式下?

考虑这个程序:

#include <iostream>

template<bool Debug = false, int Line = __LINE__>
constexpr int adds(const int& a, const int& b) { 
    if (Debug)
        std::cout << __FUNCTION__ << " called on line " << Line << '\n';
    return (a + b);
}

int main() {
    std::cout << adds(3, 7) << '\n';
    std::cout << adds<true, __LINE__> (5, 9) << '\n';
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我尝试在DebugVisual Studio 2017 模式下编译和构建它时,会生成这些编译器错误:

1>------ Build started: Project: Simulator, Configuration: Debug x64 ------
1>main2.cpp
1>c:\***\main2.cpp(12): error C2672: 'adds': …
Run Code Online (Sandbox Code Playgroud)

c++ compiler-errors visual-c++ compiler-bug visual-studio-2017

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

试图理解std :: forward,std :: move更好一点

我正在编写一个基本的类模板.它的参数需要两种参数类型.该类的想法是将一种类型作为a const ref和另一种作为a ref.该类的功能是将类型转换为创建对象最终的A类型.我想有或该类模板的有效组成部分.Bbperfect-forwardingmove semantics


现在这里是我目前只有基本类型的类,但计划使用可变参数构造将其扩展为任何两种类型.

#ifndef CONVERTER_H
#define CONVERTER_H

#include <utility>

template<class From, class To>
class Converter {
private:
    From in_;
    To   out_;

public:
    // Would like for From in to be a const (non modifiable) object
    // passed in by perfect forwarding or move semantics and for 
    // To out to be returned by reference with perfect forwarding 
    // or move semantics. Possible Constructor Declarations - Definitions

    // Using std::move …
Run Code Online (Sandbox Code Playgroud)

c++ templates std move-semantics perfect-forwarding

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

为什么这个函数产生不正确的值?

我有一个简单的函数模板来计算容器的平均值:

template<typename T>
T array_average( std::vector<T>& values ) {
    if( std::is_arithmetic<T>::value ) {
        if( !values.empty() ) {
            if( values.size() == 1 ) {
                return values[0];
            } else { 
                return (static_cast<T>( std::accumulate( values.begin(), values.end(), 0 )  ) / static_cast<T>( values.size() ) );
            }
        } else {
            throw std::runtime_error( "Can not take average of an empty container" ); 
        }
    } else {
        throw std::runtime_error( "T is not of an arithmetic type" );
    }
}
Run Code Online (Sandbox Code Playgroud)

我在static_cast<>上面添加了s,试图强制计算到所需的类型<T>.

当我在main中调用此函数时使用 uint64_t

std::vector<uint64_t> …
Run Code Online (Sandbox Code Playgroud)

c++ templates stdvector

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

C++ 中的编译时 Base64 解码

是否可以在编译时将 base64 编码数据解码为二进制数据?

我想到了这样的事情:

constexpr auto decoded = decodeBase64<"SGVsbG8=">();

或者

constexpr auto decoded = decodeBase64("SGVsbG8=");

我对生成的decoded.

c++ compile-time constexpr c++17

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

尝试在 C++ 中使用递归组合模板化多项式类的相似项

我正在自学 C++。

我正在尝试组合多项式。为此,我使用简单的值组合定义了简单的类: Polynomial<T>,Term<T>Coefficient<T>(也可能只是 complex<T>)。我已经定义了所需的运算符重载。

多项式的比较通过对它们的项进行排序 ( std::sort)。

我正在工作combineLikeTerms();调用此方法时,将首先调用另一个成员方法,该方法将对此项向量进行排序。例如:

4x^3 + 5x^2 + 3x - 4 
Run Code Online (Sandbox Code Playgroud)

将是一个可能的结果排序向量。

问题

我在这个向量上使用了两个迭代器,我试图合并相同顺序的相邻项。

假设我们排序后的初始向量是这样的:

4x^3 - 2x^3 + x^3 - 2x^2 + x ...
Run Code Online (Sandbox Code Playgroud)

在函数完成其迭代后,临时堆栈向量将如下所示 2x^3 + x^3 - 2x^2 + x ...如果我们看起来仍然需要再次重构的术语。

我该怎么做呢?我正在考虑使用递归。

// ------------------------------------------------------------------------- //
// setPolynomialByDegreeOfExponent()
// should be called before combineLikeTerms
template <class T>
void Polynomial<T>::setPolynomialByDegreeOfExponent()
{
    unsigned int uiIndex = _uiNumTerms - 1;
    if ( uiIndex < …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm recursion templates vector

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

在实践现代 C++17 最佳实践的同时管理线程

最初我曾想过设计一个ThreadManager类来threads与它们一起存储data type objects并且function type objects可以使用。该类负责管理内存、访问、传输、释放、锁定、解锁、加入和标准多线程库中相关类型的其他典型通用功能。它最初的目的是将包含线程及其 id 与特定线程可以访问的一组特定资源相关联。

通过文档阅读后cppreferencemutexshared_mutexlock_guardshared_lockstd::function<...>,等现在知道mutexeslock_guards是非可复制,事实上,如果我模板类存储任意function objectsfunction pointerslambdasstd::function<>S作为std::function<>这个类的容器内的这一类的实例化预期的单例只能存储特定的函数签名,将其限制为无法实例化任何其他声明签名。

关于为标准库中的多线程库的这些行为和属性mutexesshared_mutexes lock_guardsthreadspromisesfutures等...它来到介意,我这个得太多类的整体设计。

您可以通过我之前提出的这个问题来参考我最初的设计尝试。在不知道它们的声明签名的情况下将任意函数对象存储到类成员容器中,这应该让您了解我正在尝试做什么。


进一步了解他们的行为、属性和职责,我想知道以下内容是否适合预期的设计过程。

而不是存储任何mutexes, lock_guards, threads,data type objectsfunction objects; 仅存储 生成idsthreads,并让我的管理器类更像监视、记录和报告类型类是否更有意义? …

c++ multithreading mutex class-design c++17

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

c ++ 17聚合初始化

我正在观看由Jason Tuner在youtube上播放的视频系列,并在此处发现的这个特定视频:聚合初始化他开始使用clang ++ c ++ 03然后将编译器更改为clang ++ c ++ 11然后当他合并基类层次结构时他改变了它使用c ++ 17或c ++ 1z使用最近的clang ++构建.

我刚刚下载并安装了MSVS2017RC,我在Intel Quad Core Extreme上运行Windows 7 64bit SP1.

但是当我在我的IDE中尝试跟踪他的视频时

struct B {
    double q;
};

struct S : B {
    int i;
    float f;
};

int main() {
    S s{ {}, 1, 2.3f };
    return s.f;
}
Run Code Online (Sandbox Code Playgroud)

我收到此编译器错误:

1>------ Build started: Project: Test1z, Configuration: Debug Win32 ------
1>stdafx.cpp
1>Test1z.cpp
1>c:\users\skilz80\documents\visual studio 2017\projects\test1z\test1z\test1z.cpp(15): error C2440: 'initializing': cannot convert from 'initializer list' to 'S'
1>c:\users\skilz80\documents\visual studio …
Run Code Online (Sandbox Code Playgroud)

c++ visual-c++ aggregate-initialization c++17 visual-studio-2017

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

如何使用 __LINE__ 或其他方法从呼叫站点获取行号?

考虑一下我写的这个简短的程序:

    #include <iostream>
    
    template<bool Debug = false>
    constexpr int add(const int& a, const int& b) { 
        if (Debug)
            std::cout << __FUNCTION__ << " called on line " << __LINE__ << '\n';
        return (a + b);
    }
    
    int main() {
        std::cout << add(3, 7) << '\n';
        std::cout << add<true>(5, 9) << '\n';
        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

它工作得很好,并且提供了正确的输出:

10
add called on line 6
14
Run Code Online (Sandbox Code Playgroud)

但是,我希望打印的行号是程序调用站点上的行,在该程序中应该是第 12 行。

那么我如何使用__LINE__或其他一些方法来给我调用函数的行号?

所需的输出是:

10
add called on line 12
14
Run Code Online (Sandbox Code Playgroud)

如果可能,我希望它从函数本身生成。


-编辑-

作为对读者的说明,我对任何和所有选项都持开放态度,但对于我当前的构建环境,我仅限于 C++17,并且我正在使用 …

c++ macros preprocessor line-numbers visual-studio-2017

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

前进或移动或不移动;如何确定在类使用的上下文中哪个是首选?

class Test {
public:
    typedef std::set<std::pair<double, double>> DataSet;

    explicit Test(const DataSet&& d) {
        for (auto &itr : d) {
            std::cout << "value1 = " << itr.first << '\n';
            std::cout << "value2 = " << itr.second << '\n';
        }
    }

};

int main() {
    //using namespace util;
    try {
        // Forwarding
        Test obj( std::forward<Test::DataSet>(
            { 
              { 10.0, 20.0 },
              { 30.0, 40.0 },
              { 50.0, 60.0 }
            }
        ));

        std::cout << '\n';

        // Move
        Test obj2(std::move(Test::DataSet(
            {
              { 10.0, 20.0 }, …
Run Code Online (Sandbox Code Playgroud)

c++ std move-semantics perfect-forwarding c++17

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