我正在尝试使用lambda作为静态成员,如下所示:
struct A
{
static constexpr auto F = [](){};
};
int main()
{
A::F();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是否是正确的C++ 11代码?在clang上,我收到此错误:
error: constexpr variable 'F' must be initialized by a constant
expression
static constexpr auto F = [](){};
^~~~~~
Run Code Online (Sandbox Code Playgroud)
似乎在铿锵声中,lambdas不被视为常数表达.它是否正确?也许他们还没有在clang中完全实现lambdas,因为gcc 4.7似乎允许它作为a constexpr,但是它给出了另一个错误:
error: ‘constexpr const<lambda()> A::F’, declared using local type ‘const<lambda()>’, is used but never defined
Run Code Online (Sandbox Code Playgroud)
我不确定,我明白这意味着什么.它似乎正确地推断出lambda的类型,但它只声明它而不是定义它.我该如何定义它?
所以我正在尝试为Android构建boost 1.55,但我得到了Boost.System和Boost.Atomic的链接错误,即"错误:找不到-lrt".当然,android没有librt,因为它内置于C运行时.所以,我试图获得提升,因此它不会链接到librt.我尝试删除源代码中的每个"-lrt":
find . -type f | xargs -n1 -P 8 sed -i "s/-lrt//g"
Run Code Online (Sandbox Code Playgroud)
但我仍然得到同样的错误.如何使升级不链接librt for android?
当我尝试编译这个测试程序时:
struct comma_guard
{
template<class T>
const comma_guard& operator,(T&&) const
{
return *this;
}
};
struct foo {};
template<class T> T operator,(T x, foo)
{
return x;
}
int main()
{
(comma_guard(), foo());
}
Run Code Online (Sandbox Code Playgroud)
我在clang上遇到编译错误:
comma_guard.cpp:20:19: error: use of overloaded operator ',' is ambiguous (with operand types 'comma_guard' and 'foo')
(comma_guard(), foo());
~~~~~~~~~~~~~^ ~~~~~
comma_guard.cpp:6:24: note: candidate function [with T = foo]
const comma_guard& operator,(T&&) const
^
comma_guard.cpp:13:21: note: candidate function [with T = comma_guard]
template<class T> T operator,(T x, …Run Code Online (Sandbox Code Playgroud) 我想从目标生成cmake中的pkgconfig文件.我盯着写下这样的东西:
function(auto_pkgconfig TARGET)
get_target_property(INCLUDE_DIRS ${TARGET} INTERFACE_INCLUDE_DIRECTORIES)
string(REPLACE "$<BUILD_INTERFACE:" "$<0:" INCLUDE_DIRS "${INCLUDE_DIRS}")
string(REPLACE "$<INSTALL_INTERFACE:" "$<1:" INCLUDE_DIRS "${INCLUDE_DIRS}")
string(REPLACE "$<INSTALL_PREFIX>" "${CMAKE_INSTALL_PREFIX}" INCLUDE_DIRS "${INCLUDE_DIRS}")
file(GENERATE OUTPUT ${TARGET}.pc CONTENT "
Name: ${TARGET}
Cflags: -I$<JOIN:${INCLUDE_DIRS}, -I>
Libs: -L${CMAKE_INSTALL_PREFIX}/lib -l${TARGET}
")
install(FILES ${TARGET}.pc DESTINATION lib/pkgconfig)
endfunction()
Run Code Online (Sandbox Code Playgroud)
这是一个简化版本,但它基本上读取INTERFACE_INCLUDE_DIRECTORIES属性并处理INSTALL_INTERFACE生成器表达式.只要在调用之前设置了include目录,这样就可以正常工作auto_pkgconfig,如下所示:
add_library(foo foo.cpp)
target_include_directories(foo PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>
${OTHER_INCLUDE_DIRS}
)
auto_pkgconfig(foo)
Run Code Online (Sandbox Code Playgroud)
但是,有时会在调用之后设置属性auto_pkgconfig,如下所示:
add_library(foo foo.cpp)
auto_pkgconfig(foo)
target_include_directories(foo PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>
${OTHER_INCLUDE_DIRS}
)
Run Code Online (Sandbox Code Playgroud)
但是,这将无法正确读取包含目录.我希望auto_pkgconfig在设置所有目标属性后运行.我可以使用生成器表达式,通过更改auto_pkgconfig为:
function(auto_pkgconfig TARGET)
file(GENERATE OUTPUT ${TARGET}.pc CONTENT " …Run Code Online (Sandbox Code Playgroud) 当我编译该程序时:
#include <list>
int main() {
std::list<int> l = {1, 2};
l.remove(l.front());
}
Run Code Online (Sandbox Code Playgroud)
使用ASAN和调试进行clang:
clang++-8 -fno-omit-frame-pointer -g -fsanitize=address -D_GLIBCXX_DEBUG -std=c++11 list-remove.cpp
Run Code Online (Sandbox Code Playgroud)
我得到了heap-use-after-free:
==31868==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000000020 at pc 0x0000004fa1ae bp 0x7fff52cc5630 sp 0x7fff52cc5628
READ of size 4 at 0x603000000020 thread T0
#0 0x4fa1ad in std::__debug::list<int, std::allocator<int> >::remove(int const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/debug/list:649:18
#1 0x4f990f in main /tmp/list-remove.cpp:5:7
#2 0x7ff27d974b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
#3 0x41b879 in _start (/tmp/list-remove+0x41b879)
Run Code Online (Sandbox Code Playgroud)
似乎当removefinds x与第一个元素匹配时,它将从列表中删除该元素并将其删除。当检查第二个元素时,它将使用x已删除的元素来比较该元素。
根据C ++标准,这是正确的实现吗?最好先将元素移到末尾再删除它们。这样可以避免heap-use-after-free错误,但是也许不需要这样的实现。
从 …
我有一个函数对象,其中包含一个显式的(即非推导的)模板参数,如下所示:
struct foo
{
template<class T>
T operator()() const
{
return 5;
}
};
foo bar = {};
Run Code Online (Sandbox Code Playgroud)
当我尝试这样称呼时:
int main()
{
int i = bar<int>();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我收到编译错误.有没有办法像常规函数一样用模板参数调用函数对象?我真的需要将它作为一个函数对象.制作一个免费功能对我来说并不是一个真正的选择(或者至少,它是一个非常混乱的选项).
所以我这里有一些使用 gcc、clang 和 msvc 编译的代码:
#include <cstdio>
#include <type_traits>
struct c_class;
template <class T> struct holder { friend auto adl_lookup(holder<T>); };
template <class C, class T> struct lookup {
friend auto adl_lookup(holder<T>) { return holder<C>{}; }
};
struct cpp_class : lookup<cpp_class, c_class *> {
cpp_class() {}
};
int main() {
static_assert(std::is_same<holder<cpp_class>,
decltype(adl_lookup(holder<c_class *>{}))>{},
"Failed");
}
Run Code Online (Sandbox Code Playgroud)
之所以在类adl_lookup中定义lookup而不是在类中定义,是为了在继承CRTP类时holder可以从c_class到进行“反向”查找。所以友元函数不能移到类中。cpp_classlookup<cpp_class, c_class *>holder
但是,在 gcc 上,我收到有关非模板友元函数的警告:
<source>:9:37: warning: friend declaration 'auto adl_lookup(holder<T>)' declares a …Run Code Online (Sandbox Code Playgroud)