小编Vit*_*meo的帖子

对CMake的缓存变量设置优先级感到困惑

我对CMake的缓存变量感到困惑:

  • 案例1:CACHE+FORCE

    set(CMAKE_CXX_FLAGS "myflags" CACHE STRING "" FORCE)
    
    Run Code Online (Sandbox Code Playgroud)
    • 第一次CMake运行: 按预期"myflags"显示在CMakeCache.txt文件中.
    • 命令行选项:命令行选项不覆盖"myflags"- 似乎FORCE比命令行-D...="..."参数具有更高的优先级.这是不希望的 - 我希望命令行参数覆盖"myflags".

  • 案例2:仅限 CACHE

    set(CMAKE_CXX_FLAGS "myflags" CACHE STRING "")
    
    Run Code Online (Sandbox Code Playgroud)
    • 第一次CMake运行:CMakeCache.txt文件中没有任何内容.我希望"myflags"第一次出现.
    • 命令行选项:命令行优先于"myflags".

我对我的结论是否正确?或者做"默认变量",例如CMAKE_CXX_FLAGS表现不同?

有没有办法在第一次CMake运行期间"myflags"写入CMakeCache.txt文件(之前没有在此文件夹中运行CMake)?

我想"myflags"在缓存中的第一次CMake运行期间设置,然后允许用户使用命令行覆盖它.

如果我使用FORCE,用户不能通过命令行覆盖它.

如果我不使用FORCE,"myflags"在第一次运行期间不会写入缓存文件.

caching cmake

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

使用`void_t`来检测多个继承类型的重复错误

我想实现一个has_no_duplicates<...>类型特征,评估std::true_type传递的可变参数类型列表是否没有重复类型.

static_assert(has_no_duplicates<int, float>{}, "");
static_assert(!has_no_duplicates<float, float>{}, "");
Run Code Online (Sandbox Code Playgroud)

让我们假设,对于这个问题的范围,我想使用多重继承来做到这一点.

当一个类多次从同一类型继承时,会发生错误.

template<class T> 
struct type { };

template<class... Ts>
struct dup_helper : type<Ts>... { };

// No errors, compiles properly.
dup_helper<int, float> ok{};

// Compile-time error: 
// base class 'type<float>' specified more than once as a direct base class
dup_helper<float, float> error{};
Run Code Online (Sandbox Code Playgroud)

我以为我已经习惯于void_t"检测"这个错误,但是我无法在cppreference的代码示例之后实现一个有效的解决方案.

这是我试过的:

template<class, class = void>
struct is_valid 
    : std::false_type { };

// First try:
template<class T>
struct is_valid<T, std::void_t<decltype(T{})>> 
    : std::true_type …
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic-functions sfinae c++17

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

C++ 17的类模板的"模板参数推导"可以推导出本地类型吗?

P0091R3 ("类模板的模板参数推导")最近添加到gcc主干,可以在wandbox上进行测试.

我想到的是在很少的代码行中用它来实现"范围保护"的可能性 :

scope_guard _([]{ cout << "hi!\n" });
Run Code Online (Sandbox Code Playgroud)

我尝试在wandbox上实现它 ...

template <typename TF>
struct scope_guard : TF
{
    scope_guard(TF f) : TF{f} { }
    ~scope_guard() { (*this)(); }
};

int main() 
{
    scope_guard _{[]{}};
}
Run Code Online (Sandbox Code Playgroud)

...但编译失败,出现以下错误:

prog.cc:6:5: error: 'scope_guard(TF)-> scope_guard<TF> [with TF = main()::<lambda()>]', declared using local type 'main()::<lambda()>', is used but never defined [-fpermissive]
     scope_guard(TF f) : TF{std::move(f)} { }
     ^~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

然后我尝试使用非lambda本地类型,并得到相同的错误.

int main() 
{
    struct …
Run Code Online (Sandbox Code Playgroud)

c++ gcc templates template-argument-deduction c++17

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

应用"类模板的模板参数推导"是否应该为可变参数类模板推导出空参数包?

"类模板参数推导"的提案(P0091R2)包含以下例子:

template<class ... Ts> struct X { X(Ts...) };
X x1{1}; // OK X<int>
X x11; // OK X<>
Run Code Online (Sandbox Code Playgroud)

(除了构造函数定义缺少一个主体的事实)之外,该示例似乎建议使用空参数包推导出使用零参数构造的可变参数类模板.

不幸的是,最新版本的g ++不同意:

int main()
{
    X x1{1};
    X x11;
}
Run Code Online (Sandbox Code Playgroud)

 In function 'int main()':
 error: invalid use of template-name 'X' without an argument list
 X x11;
 ^
 note: class template argument deduction requires an initializer
Run Code Online (Sandbox Code Playgroud)

wandbox上的示例


我无法在提案中找到明确的措辞来澄清这种互动.这里的g ++错了吗?

c++ templates language-lawyer template-argument-deduction c++17

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

神秘的UB /段错误只在gcc上 - 代码是不正确的?

#include <utility>

template <typename P, typename F>
struct foo
{
    P _p;
    int i{0};

    foo(P&& p, F) : _p{std::move(p)} { }

    template <typename... Cs>
    void up(Cs&... cs)
    {
        if constexpr(sizeof...(Cs) == 2) { down(cs...); }
        else { _p.up(*this, cs...); }
    }

    void down() { --i; }

    template <typename C, typename... Cs>
    void down(C& c, Cs&... cs)
    {
        [&] { [&] { c.down(cs...); }(); }();
    }
};

int main()
{
    auto f = foo{foo{foo{0, 0}, 0}, 0};
    f.up();
}
Run Code Online (Sandbox Code Playgroud)

上面的代码片段:

  • 使用g …

c++ gcc segmentation-fault undefined-behavior c++17

8
推荐指数
0
解决办法
123
查看次数

`std :: stringstream :: fail()`读取后再写什么值?(gcc vs clang)

请考虑以下代码段:

#include <iostream>
#include <sstream>

int main()
{
    std::stringstream ss;
    ss << "12345";
    unsigned short s;
    ss >> s;
    ss << "foo";

    std::cout << std::boolalpha
              << "\nss.eof()  = " << ss.eof()
              << "\nss.good() = " << ss.good()
              << "\nss.bad()  = " << ss.bad()
              << "\nss.fail() = " << ss.fail()
              << "\nss.str()  = " << ss.str();
}
Run Code Online (Sandbox Code Playgroud)

clang ++ trunk打印出以下结果:

ss.eof()  = true
ss.good() = false
ss.bad()  = false
ss.fail() = false
ss.str()  = 12345
Run Code Online (Sandbox Code Playgroud)

在wandbox上


g ++ trunk打印以下结果:

ss.eof()  = …
Run Code Online (Sandbox Code Playgroud)

c++ iostream sstream language-lawyer

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

constexpr函数与未使用的引用参数 - gcc vs clang

请考虑以下代码:

template <int N, typename T> void f(T) { }

template <typename T> 
constexpr int k(T&) { return 0; }

int main() 
{
    constexpr auto i = 1;
    f<k(i)>([&i]
    {
         f<k(i)>(0); 
    });
}
Run Code Online (Sandbox Code Playgroud)

clang++ (主干)编译它.g++ (trunk)因以下错误而失败:

<source>: In lambda function:

<source>:11:19: error: no matching function for call to 'f<k<const int>((* & i))>(int)'
11  |          f<k(i)>(0);
    |                   ^

<source>:1:35: note: candidate: 'template<int N, class T> void f(T)'
    1 | template <int N, typename T> void f(T) { } …
Run Code Online (Sandbox Code Playgroud)

c++ templates language-lawyer constexpr c++17

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

正确的方式来声明/定义类似自定义cout的对象

我创建了自己std::cout的对象,它既可以写入std::cout日志文件,也可以写入日志文件.

我目前正在头文件中定义它,但我收到了未使用的变量警告.

头文件 <MyLib/Log.h>

static LOut { };
static LOut lo;

template<typename T> inline LOut& operator<<(LOut& mLOut, const T& mValue)
{
    std::string str{toStr(mValue)};
    std::cout << str;
    getLogStream() << str;
    return mLOut;
}
Run Code Online (Sandbox Code Playgroud)

用法:

#include <MyLib/Log.h>
...
lo << "hello!" << std::endl;
Run Code Online (Sandbox Code Playgroud)

应该lostatic?应该loextern

Kudos用于解释声明类似cout对象的正确方法,并展示主标准库实现如何实现它.


编辑:by- coutlike对象,我的意思是一个全局变量,在包含相应的头之后始终可用.

c++ static global-variables extern c++11

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

用于统一块集合中的连续块的算法

我正在创建一个具有动态内存块大小的预分配器,我需要统一连续的内存块.

struct Chunk // Chunk of memory
{
    Ptr begin, end; // [begin, end) range
}

struct PreAlloc
{
    std::vector<Chunk> chunks; // I need to unify contiguous chunks here
    ...
}
Run Code Online (Sandbox Code Playgroud)

我尝试了一个天真的解决方案,在根据它们对块进行排序后begin,基本上通过向量检查是否下一个块begin是否等于当前块end.我相信它可以改进.

是否有一个很好的算法来统一连续的范围

信息:

  • 大块永远不会"重叠".
  • 块可以具有大于0的任何大小.
  • 性能是最重要的因素.

c++ memory sorting algorithm c++11

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

让一位同事相信他们是否没有被嵌套

今年开始编程的我的一位大学同事有时写下这样的陈述:

if(something) doA();
else
    if(something2) doC();
    else doD();
Run Code Online (Sandbox Code Playgroud)

他被认为第二if-else对被视为单个实体,并且它实际上嵌套在第一对之下else.

但是,我确信他的代码相当于:

if(something) doA();
else if(something2) doC();
else doD();
Run Code Online (Sandbox Code Playgroud)

这表明第二个else实际上并不是嵌套的,而是与第一个if相同的级别.我告诉他,他需要用花括号来达到他想要的效果.

"但我的代码按预期工作!"

事实上,它按预期工作.事实证明代码的行为是相同的,即使else没有嵌套.

令人惊讶的是,我发现自己无法写出一个清晰简洁的例子,显示出不同的行为

if(something) doA();
else
    if(something2) doC();
    else doD();
Run Code Online (Sandbox Code Playgroud)

if(something) doA();
else {
    if(something2) doC();
    else doD();
}
Run Code Online (Sandbox Code Playgroud)

你能帮我找一个例子,告诉我的同事使用/不使用花括号之间的区别吗?

或者,就行为而言,看起来不正确的版本总是等同于花括号的版本?

c c++ if-statement nested

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