是static_cast<T>(...)在编译时还是在运行时完成的事情?我用Google搜索了但我得到了不同的答案.
此外,dynamic_cast<T>(...)显然是运行时 - 但是呢reinterpret_cast<T>(...)?
我需要将一些预定义的参数和一些用户传递的参数转发给成员函数.
#define FWD(xs) ::std::forward<decltype(xs)>(xs)
template<class T, class... Ts, class... TArgs>
void forwarder(void(T::*fptr)(Ts...), TArgs&&... xs)
{
T instance;
(instance.*fptr)(FWD(xs)..., 0);
// ^
// example predefined argument
}
forwarder(&example::f0, 10, 'a');
forwarder(&example::f1, 10, "hello", 5);
Run Code Online (Sandbox Code Playgroud)
这适用于非模板成员函数.
forwarder但是,传递给can 的成员函数指针也指向模板函数.不幸的是,T在这种情况下,编译器无法推断出类型:
struct example
{
void f0(int, int) { }
template<class T>
void f1(T&&, int) { }
};
// Compiles
forwarder(&example::f0, 10);
// Does not compile
forwarder(&example::f1, 10);
Run Code Online (Sandbox Code Playgroud)
错误:
prog.cpp:30:28: error: no matching function for call to 'forwarder(<unresolved overloaded function type>, int)' …Run Code Online (Sandbox Code Playgroud) int main()
{
auto l = [x = 10]() -> decltype(x) {};
}
Run Code Online (Sandbox Code Playgroud)
clang ++ 4.0拒绝此代码时出现以下错误:
error: use of undeclared identifier 'x'
auto l = [x = 10]() -> decltype(x) {};
^
Run Code Online (Sandbox Code Playgroud)g ++ 7拒绝此代码时出现以下错误:
In function 'int main()':
error: 'x' was not declared in this scope
auto l = [x = 10]() -> decltype(x) {};
^
error: 'x' was not declared in this scope
In lambda function:
warning: no return statement in function returning non-void …Run Code Online (Sandbox Code Playgroud)请考虑以下代码:
template <typename F, typename X0, typename X1, typename... Xs>
auto fold_left(F&& f, X0&& x0, X1&& x1, Xs&&... xs)
{
auto acc = f(x0, x1);
return ([&](auto y){ return acc = f(acc, y); }(xs), ...);
}
const std::string a{"a"}, b{"b"}, c{"c"}, d{"d"}, e{"e"};
const auto cat = [](auto x, auto y) { return "(" + x + ", " + y + ")"; };
Run Code Online (Sandbox Code Playgroud)
在调用和打印时fold_left(cat, a, b, c),g ++ 7和clang ++ 5输出:
((a,b),c)
当调用和打印fold_left(cat, a, b, c, …
今天我遇到了一些大致类似于以下代码段的代码.二者valgrind并UndefinedBehaviorSanitizer检测读取未初始化的数据.
template <typename T>
void foo(const T& x)
{
static_assert(std::is_pod_v<T> && sizeof(T) > 1);
auto p = reinterpret_cast<const char*>(&x);
std::size_t i = 1;
for(; i < sizeof(T); ++i)
{
if(p[i] != p[0]) { break; }
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
p[i] != p[0]当传递包含填充字节的对象时,上述工具抱怨比较foo.例:
struct obj { char c; int* i; };
foo(obj{'b', nullptr});
Run Code Online (Sandbox Code Playgroud)
从POD类型中读取填充字节并将它们与其他内容进行比较是不确定的行为?我无法在Standard和StackOverflow中找到明确的答案.
c++ padding undefined-behavior language-lawyer standard-layout
考虑以下代码:
#include <type_traits>
int main()
{
auto l = [k = 0]
{
static_assert(std::is_same_v<decltype(k), int>);
};
}
Run Code Online (Sandbox Code Playgroud)
clang++ (10.x 和主干)愉快地编译了上面的代码。
g++ (10.x 和主干)无法编译上面的代码并出现以下错误:
Run Code Online (Sandbox Code Playgroud)error: static assertion failed 10 | static_assert(std::is_same_v<decltype(k), int>); | ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
显然,g++相信decltype(k)评估为const int。
由于数据成员的类型k应该从0(这是一个普通的,非const, int)推导出来,我认为这是一个g++错误。在我的心智模式,这是唯一的事情const是operator()拉姆达的,而不是合成的数据成员k。
我的评估是否正确?
标准怎么说?
如何获得用作模板参数的任意函数类型的arity?
该函数可以是普通函数,lambda或函子.例:
template<typename TFunc>
std::size_t getArity()
{
// ...?
}
template<typename TFunc>
void printArity(TFunc mFunc)
{
std::cout << "arity: " << getArity<TFunc>() << std::endl;
}
void testFunc(int) { }
int main()
{
printArity([](){}); // prints 0
printArity([&](int x, float y){}); // prints 2
printArity(testFunc); // prints 1
}
Run Code Online (Sandbox Code Playgroud)
我可以访问所有C++ 14功能.
我是否必须为每种函数类型(以及所有相应的限定符)创建特化?或者有更简单的方法吗?
我是"基于lambda的foreach循环"的粉丝:
class SomeDataStructure
{
private:
std::vector<SomeData> data;
public:
template<typename TF> void forData(TF mFn)
{
for(int i{0}; i < data.size(); ++i)
mFn(i, data[i]);
}
};
SomeDataStructure sds;
int main()
{
sds.forData([](auto idx, auto& data)
{
// ...
});
}
Run Code Online (Sandbox Code Playgroud)
我认为这对于更复杂的数据结构来说是一个很好的抽象,因为它允许用户使用其他参数直观地循环其内容.并且编译器优化应该保证性能等于传统for(...)循环.
不幸的是,像这样使用Lambda表达式显然阻止了使用有时是有用的continue;和break;陈述.
sds.forData([](auto idx, auto& data)
{
// Not valid!
if(data.isInvalid()) continue;
});
Run Code Online (Sandbox Code Playgroud)
有没有办法模拟continue;和break;语句没有任何性能损失,并没有使语法不方便?
std::variant 提供以下访问功能:
std::get_if:取指针到variant,返回指针替代.
template <std::size_t I, typename... Ts>
auto* std::get_if(std::variant<Ts...>* pv) noexcept;
Run Code Online (Sandbox Code Playgroud)
如果
pv不是空指针pv->index() == I,则返回指向存储在指向的变量中的值的指针pv.否则,返回空指针值.
这意味着get_if实现大致如下:
template <std::size_t I, typename... Ts>
auto* std::get_if(std::variant<Ts...>* pv) noexcept
{
if(pv == nullptr) return nullptr;
if(pv->index() != I) return nullptr;
return &(pv->real_get<I>());
}
Run Code Online (Sandbox Code Playgroud)std::get:取基准来variant,回到参考替代,throw对非法访问.
template <std::size_t I, typename... Ts>
auto& std::get(std::variant<Ts...>& v);
Run Code Online (Sandbox Code Playgroud)
如果
v.index() == I,则返回对存储的值的引用v.否则,抛出std::bad_variant_access …
我发现了一个代码片段,它在clang ++ 4(和trunk)中编译并正常工作,但无法在g ++ 7(和trunk)中编译.我们假设我有以下struct类型:
struct a { void foo() { } };
struct b { void bar() { } };
struct c { void bar() { } };
Run Code Online (Sandbox Code Playgroud)
我想创建一个过载设定的lambda表达式哪些处理a明确,而b与c被"捕获"用一个通用的λ auto参数:
auto ol = overload([](a x) { x.foo(); },
[](auto x){ x.bar(); })
Run Code Online (Sandbox Code Playgroud)
当我调用时ol(a{}):
铛++编译和行为与预期:a"匹配"的第一拉姆达,而b与c匹配第二个.
g ++无法编译,出现以下错误:
error: 'struct a' has no member named 'bar' …Run Code Online (Sandbox Code Playgroud)