C++ std命名空间包含辅助函数std::not1和std::not2.它们分别采用一元或二元谓词仿函数,并分别返回一个std::unary_negate或std::binary_negate谓词.
我想知道是否应该使用一些模板魔术来实现
template<typename Predicate> inline
enable_if_t<is_unary_predicate<Predicate>::value, unary_negate<Predicate> >
not_(Predicate const&pred)
{ return unary_negate<Predicate>{pred}; }
template<typename Predicate> inline
enable_if_t<is_binary_predicate<Predicate>::value, binary_negate<Predicate> >
not_(Predicate const&pred)
{ return binary_negate<Predicate>{pred}; }
Run Code Online (Sandbox Code Playgroud)
它区分了pred传递的参数以返回适当的谓词.当然,有一些奇怪的情况,传递的对象pred有两种类型的运算符(一元和二元),当这不起作用时,但这些可以在不使用这个辅助函数的情况下处理.
假设以下代码:
#include <iostream>
template<typename T>
struct Link
{
Link(T&& val) : val(std::forward<T>(val)) {}
T val;
};
template<typename T>
std::ostream& operator<<(std::ostream& out, const Link<T>& link)
{
out << "Link(" << link.val << ")";
return out;
}
template<typename T>
auto MakeLink(T&& val) -> Link<T>
{
return {std::forward<T>(val)};
}
namespace Utils {
template<typename Any>
constexpr auto RemoveLinks(const Any& any) -> const Any&
{
return any;
}
template<typename T>
constexpr auto RemoveLinks(const Link<T>& link) -> decltype(RemoveLinks(link.val))
{
return RemoveLinks(link.val);
}
} /* Utils */ …Run Code Online (Sandbox Code Playgroud) clang 3.9增加了-Wall一个-Wexpansion-to-defined产生的警告
产生'定义'的宏扩展具有未定义的行为
如果defined在#if表达式之外使用,包括随后在#if表达式中使用的宏的情况.例如以下代码
// in some file:
#define HAS_GNU (defined(__GNUC__) && !defined(__clang__))
// possibly in another file:
#if defined(__clang__) || HAS_GNU
/* ... */
#endif
Run Code Online (Sandbox Code Playgroud)
产生
test.cc:5:27: warning: macro expansion producing 'defined' has undefined behavior [-Wexpansion-to-defined]
#if defined(__clang__) || HAS_GNU
^
test.cc:3:18: note: expanded from macro 'HAS_GNU'
#define HAS_GNU (defined(__GNUC__) && !defined(__clang__))
^
test.cc:5:27: warning: macro expansion producing 'defined' has undefined behavior [-Wexpansion-to-defined]
test.cc:3:40: note: expanded from macro 'HAS_GNU' …Run Code Online (Sandbox Code Playgroud) struct foo
{
struct bar {
~bar() {} // no error w/o this line
};
bar *data = nullptr; // no error w/o this line
foo() noexcept = default; // no error w/o this line
};
Run Code Online (Sandbox Code Playgroud)
是的,我知道,还有另一个问题具有完全相同的标题,但是有一个不同的问题(涉及noexcept 运算符而没有嵌套类型).该解决方案建议有(取代的构造foo与
foo() noexcept {}
Run Code Online (Sandbox Code Playgroud)
)改变语义,这里没有必要:这里我们有一个更好的答案(因此问题不是重复).
编译器:Apple LLVM version 9.0.0 (clang-900.0.37),完整的错误信息:
test.cc:44:5: error: default member initializer for 'data' needed within definition of enclosing class 'foo' outside of member functions
foo() noexcept = default;
^
test.cc:41:10: note: …Run Code Online (Sandbox Code Playgroud) 以下代码(我无法制作更短的MVCE)
unit.h:
#include <vector>
template<typename T>
struct foo
{
std::vector<T> data;
foo(foo&&) = default; // no assembly generated
foo(std::vector<T>&&v) : data(std::move(v)) {}
};
extern template struct foo<int>; // indicates template instantiation elsewhere
Run Code Online (Sandbox Code Playgroud)
unit.cc:
#include "unit.h"
template struct foo<int>; // forces template intantiation
Run Code Online (Sandbox Code Playgroud)
main.cc:
#include "unit.h"
struct bar
{
foo<int> f;
bar(foo<int>&&x) : f(std::move(x)) {}
};
bar makeBar(int x)
{
std::vector<int> v(x);
foo<int> f(std::move(v));
return {std::move(f)};
}
int main()
{
bar x = makeBar(5);
}
Run Code Online (Sandbox Code Playgroud)
不履行铛编译(苹果LLVM版本9.0.0(铛- 900.0.39.2) - …
c++ templates explicit-instantiation c++11 template-instantiation
我正在使用自定义序列化程序创建自定义,模板繁重的序列化库。我希望能够Serializer使用SFINAE在我的库中检测和强制执行该概念(我无法访问具有概念支持的C ++ 20编译器):
class CustomSerializer
{
static T Serialize(S);
static S Deserialize(T);
};
Run Code Online (Sandbox Code Playgroud)
这里的想法是的输入类型Serialize必须等于的输出类型Deserialize,反之亦然
这可能吗?如果是这样,怎么办?
我尝试研究std::invoke_result_t,但随后需要提供参数类型。但是Deserialize的参数类型是Serialize的调用结果,并且要获取Serialize的调用结果,...
我希望您在这里看到圆形图案,这使我想知道是否有可能。
根据cppreference,std::construct_at(T*p, Args&&... args)相当于
return ::new (const_cast<void*>(static_cast<const volatile void*>(p)))
T(std::forward<Args>(args)...);
Run Code Online (Sandbox Code Playgroud)
演员“通过”的需要/目的是什么const volatile void*?换句话说,为什么construct_at不简单地等同于
return ::new (static_cast<void*>(p))
T(std::forward<Args>(args)...);
Run Code Online (Sandbox Code Playgroud)
在哪种情况下,后一种代码会导致不良行为?
我使用SSE类型进行了一些明确的矢量化计算,例如__m128(在xmmintrin.hetc中定义),但是现在我需要将向量的所有元素提升到某个(相同的)幂,即理想情况下我会想要类似的东西__m128 _mm_pow_ps(__m128, float),遗憾的是它不存在.
围绕这个最好的方法是什么?我可以存储向量,调用std::pow每个元素,然后重新加载它.这是我能做的最好的吗?编译器如何std::pow在自动矢量化代码时实现调用,否则代码可以很好地实现矢量化?有没有提供有用功能的库?
(请注意,这个问题与重复有关,当然也没有一个有用的答案.)
假设我有一个lambda
auto func = [](std::string msg) { throw std::runtime_error(msg); };
Run Code Online (Sandbox Code Playgroud)
(诚然,这个例子没什么意义,但那不是重点).如果这不是lambda,而是普通函数,我会用noreturn属性声明它
[[noreturn]] void func(std::string msg) { throw std::runtime_error(msg); }
Run Code Online (Sandbox Code Playgroud)
这也可以用于lambda吗?(我用clang 3.5尝试了几种变体,但没有任何成功.)
编辑使用Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn),我试过了
auto func = [](std::string msg) -> [[noreturn]] void { throw std::runtime_error(msg); };
Run Code Online (Sandbox Code Playgroud)
要么
auto func = [](std::string msg) [[noreturn]] { throw std::runtime_error(msg); };
Run Code Online (Sandbox Code Playgroud)
但两人都被拒绝了.这是clang 3.5的不完整/错误吗?
template<typename T=double>
constexpr T pi = T(3.14159265358979323846264338328);
template<>
constexpr const char* pi<const char*> = "?";
Run Code Online (Sandbox Code Playgroud)
使用 clang 编译器(Apple clang 版本 12.0.0)(使用 C++14),这会触发警告(使用-Weverything):
之前没有非静态变量 'pi<const char *>' 的 extern 声明
如果变量不打算在此翻译单元之外使用,则声明“静态”
此外,由于这是在标头中定义的,因此创建了多个 'myNameSpace::pi<char const*>' 实例,导致链接器错误。
因此,按照建议,我添加了static关键字,从而使警告静音:
template<>
static constexpr const char* pi<const char*> = "?";
Run Code Online (Sandbox Code Playgroud)
但是现在gcc(9.3.0)不爽,报错指向static关键字:
错误:显式模板特化不能有存储类
避免警告和错误的正确方法是什么?