小编Mat*_*szL的帖子

"constexpr if"vs"if"with optimizations - 为什么需要"constexpr"?

C++ 1z将引入"constexpr if" - 如果将根据条件删除其中一个分支.似乎合理有用.

但是,没有constexpr关键字是不可能的?我认为在编译期间,编译器应该知道编译时间是否已知.如果是,即使是最基本的优化级别也应该删除不必要的分支.

例如(参见godbolt:https://godbolt.org/g/IpY5y5 ):

int test() {
    const bool condition = true;
    if (condition) {
      return 0;
    } else {
      // optimized out even without "constexpr if"
      return 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

Godbolt探险家表示,即使是带有-O0的gcc-4.4.7也没有编译"返回1",所以它实现了constexpr所承诺的.显然,当条件是constexpr函数的结果时,这样的旧编译器将无法这样做,但事实仍然存在:现代编译器知道条件是否为constexpr,并且不需要我明确地告诉它.

所以问题是:

为什么"constexpr if"需要"constexpr"?

c++ constexpr c++17 if-constexpr

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

比较 c++20 中的多态类型

我的代码介于 c++17 和 c++20 之间。具体来说,我们在 GCC-9 和 clang-9 上启用了 c++20,它只是部分实现。

在代码中,我们有非常大的多态类型层次结构,如下所示:

struct Identifier {
    virtual bool operator==(const Identifier&other) const = 0;
};

struct UserIdentifier : public Identifier {
    int userId =0;
    bool operator==(const Identifier&other) const override {
        const UserIdentifier *otherUser = dynamic_cast<const UserIdentifier*>(&other);
        return otherUser && otherUser->userId == userId;
    }
};

struct MachineIdentifier : public Identifier {
    int machineId =0;
    bool operator==(const Identifier&other) const override {
        const MachineIdentifier *otherMachine = dynamic_cast<const MachineIdentifier*>(&other);
        return otherMachine && otherMachine->machineId == machineId;
    }
}; …
Run Code Online (Sandbox Code Playgroud)

c++ polymorphism comparison comparison-operators c++20

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

使用检测和JUnit4测试重新创建Android Activity

我想为重新创建活动编写测试.执行旋转是可选的.

我希望测试能够被谷歌"祝福"的测试框架的最新版本编写.我是编写测试的新手,所以我想学习基本的,主流的,支持良好的工具.当我掌握基础知识时,任何第三方测试框架都会没问题.而且由于我想测试非常基本的,经常出现的场景,基本工具应该足够了,对吧?

最小测试代码:

public class MainActivity extends AppCompatActivity {

    static int creationCounter = 0;
    Integer instanceId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ++creationCounter;
        instanceId = new Integer(creationCounter);
        Log.d("TEST", "creating activity " + this + ", has id " + instanceId);
    }
}
Run Code Online (Sandbox Code Playgroud)

和测试类:

@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);

    @Test
    public void useAppContext() throws Exception {

        MainActivity activity1 = mActivityTestRule.getActivity();
        int act1 = activity1.instanceId.intValue();
        int counter1 = MainActivity.creationCounter;
        assertEquals(1, counter1);
        assertEquals(1, act1);


        Log.d("TEST", …
Run Code Online (Sandbox Code Playgroud)

java instrumentation android automated-tests android-junit

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

伪造"使用包含函数的自动存储的局部变量"和c ++模板?

以下代码无法在g ++ 7.2.0中编译

template <class Internal>
class Request {
    int content = 0;
public:
    friend void setContent(int i, void *voidptr) {
        Request<Internal> *ptr = (Request<int>*)voidptr;
        ptr->content = i;
    }
    int getContent() {return content;}
};

int main() {
    Request<int> req;
    setContent(4, &req);
    return req.getContent();
}
Run Code Online (Sandbox Code Playgroud)

有错误

test.cpp: In instantiation of ‘void setContent(int, void*)’:
test.cpp:14:23:   required from here
test.cpp:7:14: error: use of local variable with automatic storage from containing function
         ptr->content = i;
         ~~~~~^~~~~~~
test.cpp:6:28: note: ‘Request<Internal>* ptr’ declared here
         Request<Internal> *ptr …
Run Code Online (Sandbox Code Playgroud)

c++ gcc templates

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

如何在运行时验证架构是否匹配 -march=?

我们用 编译我们的代码g++ -march=ivybridge -mtune=skylake。如果有人在较旧/不兼容的架构上运行,我希望应用程序能够优雅地通知并退出。我该怎么做呢?AMD处理器怎么样?是否存在某种同等的架构/指令?

c++ x86 gcc cpu-architecture

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

为什么不是来自 std::array 双向/随机访问的 ConstexprIterator?

我有一个适用于任意容器的库函数。基本上它打印元素。对于双向/随机访问容器,它首先打印和最后打印,仅首先打印单向。识别和使用双向性取决于工作--container.end()。这std::array在 C++17 中有效,但在 C++20std::arrayConstexprIterator代替了LegacyRandomAccessIterator. 阅读https://en.cppreference.com/w/cpp/named_req/ConstexprIterator似乎ConstexprIterator真的没有operator--,而是与猫有关???

在此处输入图片说明

所以我的问题是:为什么不是ConstexprIterator随机访问或至少是双向的?我的意思是,如果它在编译时工作,那么它真的应该是随机访问的。

c++ iterator constexpr

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

如何复制cmake目标

我正在我的 cmake 项目中编写函数,该函数需要从一个目标创建两个目标,并稍微更改其中之一:

option(BORG_STRIP_TEST_BINARIES OFF "Strip symbols from test binaries to reduce disk space usage" )
function(add_borg_test target)
    add_test(${target} ${target} --gtest_color=yes)
    if(BORG_STRIP_TEST_BINARIES)
        # copy target, but make it optional
        duplicate_target(FROM ${target} TO ${target}_debug )
        set_target_properties(${target}_debug PROPERTIES EXCLUDE_FROM_ALL TRUE)
        # alter
        target_link_options(${target} PRIVATE -s)
    endif()
endfunction()
Run Code Online (Sandbox Code Playgroud)

所以这应该是这样工作的:

  1. 我创建使用 gtest 的二进制目标。设置所有target_link_libraries一切。示例名称example-utests
  2. 相反添加通用add_test,我使用自定义add_borg_test
  3. 现在example-utests与标志链接-s并包含在all目标中。
  4. example-utests_debug不包含在all目标中,但当明确请求时,它链接时不带-s.

如何实现duplicate_target上面的代码片段?

cmake

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

Cmake查找模块以区分共享库或静态库

我有一个使用 libCrypto++ 的 cmake c++ 项目。我在这里托管了 FindCryptoPP.cmake 模块。重要部分是:

find_library(CryptoPP_LIBRARY
  NAMES cryptopp
  DOC "CryptoPP library"
  NO_PACKAGE_ROOT_PATH
  PATHS "/usr/lib/x86_64-linux-gnu/"
)
...
add_library(CryptoPP::CryptoPP UNKNOWN IMPORTED)
set_target_properties(CryptoPP::CryptoPP PROPERTIES
    IMPORTED_LOCATION "${CryptoPP_LIBRARY}"
    INTERFACE_INCLUDE_DIRECTORIES "${CryptoPP_INCLUDE_DIR}")
Run Code Online (Sandbox Code Playgroud)

这工作正常,找到静态库文件(*.a)。现在我想创建单独的目标 CryptoPP::CryptoPP-static 和 CryptoPP::CryptoPP-shared。安装必要的文件(默认ubuntu安装):

  • /usr/lib/x86_64-linux-gnu/libcryptopp.a
  • /usr/lib/x86_64-linux-gnu/libcryptopp.so

我想知道如何告诉 find_library 搜索静态或共享版本(最好以便携式方式 - 我需要所有 Linux、Windows、MacOS)并指定创建目标的类型。

c++ cmake shared-libraries static-libraries

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

如何找到PIE二进制文件的负载重定位?

我需要在运行的进程中获取堆栈的基地址。这将使我能够打印将由addr2line理解的原始堆栈跟踪(已剥离运行二进制文件,但addr2line可以访问符号)。我通过检查以下内容的elf标头成功做到了这一点argv[0]:我读取了入口点并将其从中减去&_start

#include <stdio.h>
#include <execinfo.h>
#include <unistd.h>
#include <elf.h>
#include <stdio.h>
#include <string.h>
void* entry_point = NULL;
void* base_addr = NULL;
extern char _start;

/// given argv[0] will populate global entry_pont
void read_elf_header(const char* elfFile) {
  // switch to Elf32_Ehdr for x86 architecture.
  Elf64_Ehdr header;
  FILE* file = fopen(elfFile, "rb");
  if(file) {
    fread(&header, 1, sizeof(header), file);
    if (memcmp(header.e_ident, ELFMAG, SELFMAG) == 0) {
        printf("Entry point from file: %p\n", (void *) header.e_entry);
        entry_point = (void*)header.e_entry;
        base_addr = …
Run Code Online (Sandbox Code Playgroud)

c linux elf aslr position-independent-code

5
推荐指数
2
解决办法
119
查看次数

cmake + clang_tidy - 禁用检查目录

我有使用 CMake 的大型项目。我想clang_tidy-8使用以下代码添加支持:

set(BORG_CLANG_TIDY OFF CACHE STRING "If enabled, clang-tidy will be used. If set to 'fix', fixes will be done on source")
set_property(CACHE BORG_CLANG_TIDY PROPERTY STRINGS ON OFF fix)
if(BORG_CLANG_TIDY)
    if (BORG_CLANG_TIDY STREQUAL "fix")
        set(maybe_fix -fix)
    endif()

    set(CMAKE_CXX_CLANG_TIDY clang-tidy-8 -extra-arg=-Wno-unknown-warning-option -format-style=file ${maybe_fix} )
endif()
Run Code Online (Sandbox Code Playgroud)

我将适当的.clang-tidy放在项目的根目录中(正确 = 带有所需的检查)。但是,有些目录我不希望 clang tidy 检查/修复(3rdparty 和遗留代码,因为它很脆弱而无法修改)。所以我尝试将空.clang-tidy文件放在这些目录中(empty = with -checks=-*)。这不起作用,因为Error: no checks enabled.

我希望找到一些假货,-checks=-*,hello-world-do-nothing-check但没有任何表现。

还有其他方法可以禁用选定子目录 (/subtrees) 中的检查吗?这些目录是静态的,如果需要,可以在 CMake 中进行硬编码。

c++ cmake clang-tidy

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

c++非类型参数包扩展

我正在编写由单一类型参数化的模板函数,并且具有可变数量的相同类型(不是不同类型)的参数。它应该检查第一个值是否在其余值中。我想这样写:

#include <unordered_set>

template <typename T>
static bool value_in(T val, T vals...) {
    // compiles, but uses only vals[0]:
    const std::unordered_set<T> allowed {vals};
    // error: pack expansion does not contain any unexpanded parameter packs:
    // const std::unordered_set<T> allowed {vals...};
    return allowed.find(val) != allowed.end();
}
// usage
enum class Enumeration {one, two, three};
int main () {
    // should return true -> 0
    return value_in(Enumeration::two,
                    Enumeration::one,
                    Enumeration::two) ? 0 : 1;
}
Run Code Online (Sandbox Code Playgroud)

我希望第二个工作,但它不编译,因为

test.cpp: In function ‘bool value_in(T, T, ...)’:
test.cpp:7:46: …
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic-functions variadic-templates c++14

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

android中的彩色折线映射api v2

我想在android maps api版本2中绘制折线.我希望它有很多颜色,最好是渐变色.在我看来,折线只允许单色.我怎样才能做到这一点?我已经有api-v1叠加绘制我喜欢的东西,所以我可以重用一些代码

public class RouteOverlayGoogle extends Overlay {
    public void draw(Canvas canvas, MapView mapView, boolean shadow) {
       //(...) draws line with color representing speed
    }
Run Code Online (Sandbox Code Playgroud)

android linear-gradients polyline android-maps-v2

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