我对CMake的缓存变量感到困惑:
案例1:CACHE+FORCE
set(CMAKE_CXX_FLAGS "myflags" CACHE STRING "" FORCE)
Run Code Online (Sandbox Code Playgroud)
"myflags"显示在CMakeCache.txt文件中."myflags"- 似乎FORCE比命令行-D...="..."参数具有更高的优先级.这是不希望的 - 我希望命令行参数覆盖"myflags".案例2:仅限 CACHE
set(CMAKE_CXX_FLAGS "myflags" CACHE STRING "")
Run Code Online (Sandbox Code Playgroud)
CMakeCache.txt文件中没有任何内容.我希望"myflags"第一次出现."myflags".我对我的结论是否正确?或者做"默认变量",例如CMAKE_CXX_FLAGS表现不同?
有没有办法在第一次CMake运行期间"myflags"写入CMakeCache.txt文件(之前没有在此文件夹中运行CMake)?
我想"myflags"在缓存中的第一次CMake运行期间设置,然后允许用户使用命令行覆盖它.
如果我使用FORCE,用户不能通过命令行覆盖它.
如果我不使用FORCE,"myflags"在第一次运行期间不会写入缓存文件.
我想实现一个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) 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) 在"类模板参数推导"的提案(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)
我无法在提案中找到明确的措辞来澄清这种互动.这里的g ++错了吗?
c++ templates language-lawyer template-argument-deduction c++17
#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 …
请考虑以下代码段:
#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打印出以下结果:
Run Code Online (Sandbox Code Playgroud)ss.eof() = true ss.good() = false ss.bad() = false ss.fail() = false ss.str() = 12345
g ++ trunk打印以下结果:
Run Code Online (Sandbox Code Playgroud)ss.eof() = …
请考虑以下代码:
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)因以下错误而失败:
Run Code Online (Sandbox Code Playgroud)<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) { } …
我创建了自己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)
应该lo是static?应该lo是extern?
Kudos用于解释声明类似cout对象的正确方法,并展示主标准库实现如何实现它.
编辑:by- coutlike对象,我的意思是一个全局变量,在包含相应的头之后始终可用.
我正在创建一个具有动态内存块大小的预分配器,我需要统一连续的内存块.
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.我相信它可以改进.
是否有一个很好的算法来统一连续的范围?
信息:
今年开始编程的我的一位大学同事有时写下这样的陈述:
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)
你能帮我找一个例子,告诉我的同事使用/不使用花括号之间的区别吗?
或者,就行为而言,看起来不正确的版本总是等同于花括号的版本?