小编Vit*_*meo的帖子

我应该总是继续使用`sink`构造函数或setter参数吗?

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++ constructor copy move c++11

20
推荐指数
2
解决办法
3425
查看次数

获取终端窗口的大小(行/列)

有没有可靠的方法来获取当前输出终端窗口的列数/行数?

我想在C/C++程序中检索这些数字.

我主要是在寻找GNU/Linux解决方案,但也需要Windows解决方案.

c c++ shell terminal

20
推荐指数
4
解决办法
2万
查看次数

"在成员函数之外的封闭类的定义中需要默认成员初始值设定项" - 我的代码是不正确的?

#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)

关于Godbolt的实例


上面的代码编译了我测试的任何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)

c++ language-lawyer c++11

20
推荐指数
1
解决办法
2462
查看次数

模板类中的变量模板 - 意外错误(可能是错误?)

有:

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)无法编译?

如果通过模板参数(在本例中)访问变量模板,似乎会出现问题 …

c++ templates auto variable-templates c++14

19
推荐指数
1
解决办法
799
查看次数

在通用lambda中使用`if constexpr`访问成员类型需要两个分支都是格式良好的 - gcc vs clang

考虑两个struct具有不同成员类型别名的s:

struct foo { using x = int;   };
struct bar { using y = float; };
Run Code Online (Sandbox Code Playgroud)

给定Ttemplate情况下,我想无论是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)

c++ sfinae language-lawyer c++17 if-constexpr

19
推荐指数
1
解决办法
363
查看次数

在继承自std :: variant的类上使用std :: visit - libstdc ++ vs libc ++

请考虑以下代码段:

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'

     inline constexpr size_t variant_size_v = variant_size<_Variant>::value;
    
                             ^~~~~~~~~~~~~~
    
    Run Code Online (Sandbox Code Playgroud)

godbolt.org上的实例


  • 两种实现都符合标准吗?

  • 如果没有,这里的实施是正确的,为什么?

c++ variant language-lawyer c++17

19
推荐指数
2
解决办法
1166
查看次数

阻止用户创建类的未命名实例

对于许多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++中的匿名变量具有"表达式范围",这意味着它们在创建它们的表达式的末尾被销毁.


有没有办法阻止用户在没有名字的情况下实例化它们? ("预防"可能过于强烈 - "使其非常困​​难"也是可以接受的).

我可以想到两种可能的解决方法,但是它们在使用类时引入了语法开销:

  1. 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.

  2. 只允许用户通过高阶函数使用警卫.

    template <typename TArgTuple, typename TF>
    decltype(auto) with_guard(TArgTuple&& guardCtorArgs, TF&& f)
    { …
    Run Code Online (Sandbox Code Playgroud)

c++ raii c++17

18
推荐指数
1
解决办法
1603
查看次数

`pair :: operator =(pair &&)`错误与`auto&`推导移动操作 - libstdc ++回归?

鉴于此计划:

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 ++ 6.2.0
  • g ++ 6.3.0
  • g ++ 7.0.1(主干)

  • clang ++ 3.9.1

  • clang ++ 5.0.0(HEAD)

在wandbox上


/* 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)

...成功编译:

  • g …

c++ libstdc++ language-lawyer move-semantics c++14

18
推荐指数
1
解决办法
384
查看次数

用“ std :: function”和先前推导的模板参数替换失败-为什么?

考虑以下代码:

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)

我收到以下错误:

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>)>);
     ^
Run Code Online (Sandbox Code Playgroud)

Godbolt.org上的实时示例

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

18
推荐指数
2
解决办法
299
查看次数

变量演绎指南不是由g ++采用的,由clang ++拍摄 - 谁是正确的?

请考虑以下代码:

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.2g ++ trunk失败了静态断言.clang ++ 5.0.0clang ++ trunk编译并按预期工作.

godbolt.org一致性观点

这是一个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)

godbolt.org一致性观点

c++ templates variadic-templates template-argument-deduction c++17

17
推荐指数
1
解决办法
456
查看次数