struct TestConstRef {
std::string str;
Test(const std::string& mStr) : str{mStr} { }
};
struct TestMove {
std::string str;
Test(std::string mStr) : str{std::move(mStr)} { }
};
Run Code Online (Sandbox Code Playgroud)
看完GoingNative 2013后,我明白接收器参数应始终按值传递并随之移动std::move.TestMove::ctor应用这个成语是正确的方法吗?有没有TestConstRef::ctor 更好/更有效的案例?
琐碎的制定者怎么样?我应该使用以下习语还是通过const std::string&?
struct TestSetter {
std::string str;
void setStr(std::string mStr) { str = std::move(str); }
};
Run Code Online (Sandbox Code Playgroud) 有没有可靠的方法来获取当前输出终端窗口的列数/行数?
我想在C/C++程序中检索这些数字.
我主要是在寻找GNU/Linux解决方案,但也需要Windows解决方案.
#include <utility>
struct foo
{
int x{0};
foo() noexcept = default;
void f() noexcept(noexcept(std::declval<foo&>())) {}
};
int main()
{
}
Run Code Online (Sandbox Code Playgroud)
上面的代码编译了我测试的任何g ++版本,以及从3.6到3.9.1的clang ++,但是没有用clang ++ 4.0.0编译:
test.cpp:6:5: error: default member initializer for 'x' needed within
definition of enclosing class 'foo' outside of member functions
foo() noexcept = default;
^
type_traits:126:26: note: in instantiation of template
class 'std::is_function<foo &>' requested here
: public conditional<_B1::value, _B1, __or_<_B2, _B3, _Bn...>>::type
^
type_traits:154:39: note: in instantiation of template
class 'std::__or_<std::is_function<foo &>,
std::is_reference<foo …Run Code Online (Sandbox Code Playgroud) 有:
struct Value
{
template<class T>
static constexpr T value{0};
};
Run Code Online (Sandbox Code Playgroud)
(0) 意思号
template<typename TValue>
struct Something
{
void x()
{
static_assert(TValue::template value<int> == 0, "");
}
};
int main() { Something<Value>{}.x(); return 0; }
Run Code Online (Sandbox Code Playgroud)
不用clang ++ 3.6编译.
错误:如果没有模板参数列表,则无法引用变量模板'value'
不使用g ++ 5.2编译.
错误:'template constexpr const T Value :: value'不是函数模板
(1) 理想
用clang ++和g ++编译.
struct Something
{
void x()
{
static_assert(Value::template value<int> == 0, "");
}
};
int main() { Something{}.x(); return 0; }
Run Code Online (Sandbox Code Playgroud)
为什么(0)无法编译?
如果通过模板参数(在本例中)访问变量模板,似乎会出现问题 …
考虑两个struct具有不同成员类型别名的s:
struct foo { using x = int; };
struct bar { using y = float; };
Run Code Online (Sandbox Code Playgroud)
给定T的template情况下,我想无论是T::x还是T::y取决于什么T是:
template <typename T>
auto s()
{
auto l = [](auto p)
{
if constexpr(p) { return typename T::x{}; }
else { return typename T::y{}; }
};
return l(std::is_same<T, foo>{});
}
int main()
{
s<foo>();
}
Run Code Online (Sandbox Code Playgroud)
g++编译上面的代码,同时clang++产生这个错误:
error: no type named 'y' in 'foo'
else { return typename …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码段:
struct v : std::variant<int, std::vector<v>> { };
int main()
{
std::visit([](auto){ }, v{0});
}
Run Code Online (Sandbox Code Playgroud)
clang ++ 7用-stdlib=libc++ -std=c++2a编译代码;
g ++ 9 -std=c++2a无法编译代码,出现以下错误:
/opt/compiler-explorer/gcc-trunk-20180711/include/c++/9.0.0/variant:94:29:错误:嵌套名称说明符中使用的不完整类型'std :: variant_size'
Run Code Online (Sandbox Code Playgroud)inline constexpr size_t variant_size_v = variant_size<_Variant>::value; ^~~~~~~~~~~~~~
两种实现都符合标准吗?
如果没有,这里的实施是正确的,为什么?
对于许多RAII"守卫"类,被实例化为匿名变量根本没有意义:
{
std::lock_guard<std::mutex>{some_mutex};
// Does not protect the scope!
// The unnamed instance is immediately destroyed.
}
Run Code Online (Sandbox Code Playgroud)
{
scope_guard{[]{ cleanup(); }};
// `cleanup()` is executed immediately!
// The unnamed instance is immediately destroyed.
}
Run Code Online (Sandbox Code Playgroud)
从这篇文章:
C++中的匿名变量具有"表达式范围",这意味着它们在创建它们的表达式的末尾被销毁.
有没有办法阻止用户在没有名字的情况下实例化它们? ("预防"可能过于强烈 - "使其非常困难"也是可以接受的).
我可以想到两种可能的解决方法,但是它们在使用类时引入了语法开销:
在detail命名空间中隐藏类并提供宏.
namespace detail
{
class my_guard { /* ... */ };
};
#define SOME_LIB_MY_GUARD(...) \
detail::my_guard MY_GUARD_UNIQUE_NAME(__LINE__) {__VA_ARGS__}
Run Code Online (Sandbox Code Playgroud)
这是有效的,但是是hackish.
只允许用户通过高阶函数使用警卫.
template <typename TArgTuple, typename TF>
decltype(auto) with_guard(TArgTuple&& guardCtorArgs, TF&& f)
{ …Run Code Online (Sandbox Code Playgroud)鉴于此计划:
struct Val
{
Val() = default;
Val(Val&&) = default;
auto& operator=(Val&&);
};
/* PLACEHOLDER */
auto& Val::operator=(Val&&) { return *this; }
Run Code Online (Sandbox Code Playgroud)
/* PLACEHOLDER */用...... 代替
int main()
{
std::vector<std::pair<int, Val>> v;
v.emplace(std::begin(v), 0, Val{});
}
Run Code Online (Sandbox Code Playgroud)
...成功编译:
g ++ 7.0.1(主干)
clang ++ 3.9.1
/* PLACEHOLDER */用...... 代替
template <typename TVec>
void a(TVec& v)
{
v.emplace(std::begin(v), 0, Val{});
}
int main()
{
std::vector<std::pair<int, Val>> v;
a(v);
}
Run Code Online (Sandbox Code Playgroud)
...成功编译:
考虑以下代码:
template <typename>
struct S { };
void g(S<int> t);
template <typename T>
void f(T, std::function<void(S<T>)>);
Run Code Online (Sandbox Code Playgroud)
尝试调用时
f(0, g);
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
Run Code Online (Sandbox Code Playgroud)error: no matching function for call to 'f' f(0, g); ^ note: candidate template ignored: could not match 'function<void (S<type-parameter-0-0>)>' against 'void (*)(S<int>)' void f(T, std::function<void(S<T>)>); ^
While I understand that generally the type of the std::function parameter can't be deduced as it is a non-deduced context
In this case T can first be deduced by the passed argument …
c++ templates language-lawyer c++11 template-argument-deduction
请考虑以下代码:
template <typename... Types>
struct list
{
template <typename... Args>
list(Args...)
{
static_assert(sizeof...(Types) > 0);
}
};
template <typename... Args>
list(Args...) -> list<Args...>;
int main()
{
list l{0, 0.1, 'a'};
}
Run Code Online (Sandbox Code Playgroud)
我希望decltype(l)如此list<int, double, char>.不幸的是,g ++ 7.2和g ++ trunk失败了静态断言.clang ++ 5.0.0和clang ++ trunk编译并按预期工作.
这是一个g ++错误吗?或者,为什么不应该遵循演绎指南?
在构造函数上添加SFINAE约束似乎提供了所需的行为:
template <typename... Args,
typename = std::enable_if_t<sizeof...(Args) == sizeof...(Types)>>
list(Args...)
{
static_assert(sizeof...(Types) > 0);
}
Run Code Online (Sandbox Code Playgroud)
c++ templates variadic-templates template-argument-deduction c++17