小编sky*_*ack的帖子

为什么需要更新范围的等效表示?

从C++ 11到C++ 17,range-for循环等效于以下代码:

{
    auto && __range = range_expression ; 
    for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) { 
        range_declaration = *__begin; 
        loop_statement 
    } 
}
Run Code Online (Sandbox Code Playgroud)

从C++ 17开始,等价将(显然)更新为这个:

{
    auto && __range = range_expression ; 
    auto __begin = begin_expr ;
    auto __end = end_expr ;
    for ( ; __begin != __end; ++__begin) { 
        range_declaration = *__begin; 
        loop_statement 
    } 
}
Run Code Online (Sandbox Code Playgroud)

乍一看,我能看到的唯一区别在于,__begin并且__end不再共享类型,只要它们(让我说)可比较.

还有其他原因需要这种改变吗?

c++ language-lawyer c++11 c++14 c++17

5
推荐指数
0
解决办法
68
查看次数

为什么SFINAE(enable_if)从类内部定义而不是外部工作

在过去的几个小时里,我一直在努力解决非常奇怪的问题(在我刚接触SFINAE并解决了5-6个其他问题之后)。基本上,在以下代码中,我希望可以f()处理所有可能的模板实例化,但是g()仅在N == 2以下情况下可用:

#include <type_traits>
#include <iostream>

template<typename T, int N>
class A
{
public:
    void f(void);
    void g(void);
};

template<typename T, int N>
inline void A<T, N>::f()
{
    std::cout << "f()\n";
}

template<typename T, int N, typename std::enable_if<N == 2, void>::type* = nullptr>
inline void A<T, N>::g()
{
    std::cout << "g()\n";
}

int main(int argc, char *argv[])
{
    A<float, 2> obj;
    obj.f();
    obj.g();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我尝试对其进行编译时,我得到一个关于3个模板参数而不是2个模板参数的错误。然后,经过一番尝试,我决定将g()内部的定义移到其A自身的定义内,如下所示:

#include <type_traits> …
Run Code Online (Sandbox Code Playgroud)

c++ templates partial-specialization sfinae enable-if

5
推荐指数
1
解决办法
1076
查看次数

“const char(&amp;a)[N]”是什么意思?

我正在检查C++11功能并看到以下代码:

class conststr {
    const char* p;
    std::size_t sz;
public:
    template<std::size_t N>
    constexpr conststr(const char(&a)[N]): p(a), sz(N - 1) {}
};
Run Code Online (Sandbox Code Playgroud)

我知道const char a[],但我很困惑const char(&a)[N],有人知道如何使用它吗?

c++ c++11

5
推荐指数
1
解决办法
2283
查看次数

CMake 和 configure_file:如果我需要 $ONLY 而不是 @ONLY 怎么办?

从 的文档来看configure_file,它有一个有用的@ONLY参数,用于:

将变量替换限制为表单的引用@VAR@。这对于配置使用${VAR}语法的脚本很有用。

到现在为止还挺好。

现在我的情况是我有一个包含@FOO@和的文件,${BAR}我想S{BAR}用一个来自我的CMakeLists.tx. 另一方面,我不希望它configure_file试图替换@FOO@.
换句话说,我需要一个类似$ONLY参数的东西,@ONLY但它适用于相反的情况。

我现在有什么机会可以做到这一点吗?
我试图把反斜线在我的面前@,但这样一来我得到一个包含几个文件\@,这不正是我需要的。

cmake

5
推荐指数
1
解决办法
873
查看次数

为什么函数返回类型中不允许参数推导?

最明显的答案可能是 - 因为标准是这样说的.
那很好,但是我正在绕着它去理解这个选择背后的原因.

请考虑以下示例:

template<typename T>
struct S { S(T) {} };

S f() { return 0; }

int main() {
    auto s = f();
    (void)s;
}
Run Code Online (Sandbox Code Playgroud)

它无法编译错误,如:

错误:使用类模板'S'需要模板参数; 函数返回类型中不允许使用参数推导

很容易修复,这不是问题,像这样的工作正常:

auto f() { return S{0}; }
Run Code Online (Sandbox Code Playgroud)

但是,我想了解在函数返回类型中允许类模板参数推导的缺点是什么.
乍一看,它看起来就像一个愚蠢的限制,但我很确定我在这里缺少一些重要的东西.

c++ templates language-lawyer argument-deduction c++17

5
推荐指数
2
解决办法
446
查看次数

静态 constexpr 成员似乎不符合 std::min

这是一个问题,其原因对我来说很模糊,但幸运的是,解决方法很容易。

考虑以下代码(让我称其为 my main.cpp):

#include <algorithm>

struct Foo {
    static constexpr float BAR = .42;

    float operator()() const noexcept {
        float zero = .0;
        return std::min(zero, BAR);
    }
};

int main() {
    Foo foo;
    foo();
}
Run Code Online (Sandbox Code Playgroud)

当我尝试编译它时,出现错误:

foob​​ar:~/stackoverflow$ g++ -std=c++11 main.cpp
/tmp/ccjULTPy.o: 在函数 'Foo::operator()() const':
main.cpp:(.text._ZNK3FooclEv[_ZNK3FooclEv] +0x1a):对‘Foo::BAR’的未定义引用
collect2:错误:ld 返回 1 个退出状态

如果我使用以下语句,也会发生同样的情况(很明显):

return std::min(zero, Foo::BAR);
Run Code Online (Sandbox Code Playgroud)

下面是上面示例的稍微修改的版本。
这个编译没有错误,即使我仍然指的是BAR成员:

#include <algorithm>

struct Foo {
    static constexpr float BAR = .42;

    float operator()() const noexcept {
        float zero = .0; …
Run Code Online (Sandbox Code Playgroud)

c++ static stl-algorithm constexpr c++11

4
推荐指数
1
解决办法
322
查看次数

是否有标准的静态函数包装类型模板?

我正在寻找一个标准的C++ 14类型模板,静态地(在编译时)嵌入一个函数引用作为模板参数,并实现operator()作为对引用函数的转发调用.

我知道std::function存在,但它将函数指针存储为数据成员.我希望将函数引用嵌入到类型签名中,以便包装器类型为默认可构造.

我有一个工作实现(使用示例用例):

#include <cstring>
#include <iostream>
#include <memory>

// Implementation:

template <typename Ret, typename... Args>
struct fn_t {
    template <Ret (Func)(Args...)>
    struct fn_ref {
        Ret operator () (Args &&...args) const {
            return Func(std::forward<Args>(args)...);
        }
    };
};

// Example use case:

template <typename T>
using unique_c_ptr = std::unique_ptr<T, fn_t<void, void *>::fn_ref<std::free>>;

int main() {
    // { char *, void (*)(void *) } (16 bytes)
    std::unique_ptr<char[], decltype(&std::free)> ptr1(::strdup("Hello"), &std::free);

    // { char …
Run Code Online (Sandbox Code Playgroud)

c++ c++14

4
推荐指数
1
解决办法
130
查看次数

JavaFX 8如何设置程序图标以发出警报?

如何在不使用的情况下将程序图标设置为警报alert.initOwner()?为什么没有initOwner?这是因为在初始化整个窗口之前必须显示一些警报,所以没有可以启用的场景initOwner

java javafx javafx-8

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

C ++-使用没有模板参数的模板类中的枚举

template<typename T> class SomeClass{

public:
    enum SomeEnum{ SOME_FLAG};

};

SomeClass::SomeEnum some_enum =      SomeClass::SomeEnum::SOME_FLAG;       //NO
SomeClass<int>::SomeEnum some_enum = SomeClass::SomeEnum::SOME_FLAG;       //NO
SomeClass<int>::SomeEnum some_enum = SomeClass<int>::SomeEnum::SOME_FLAG;  //YES
Run Code Online (Sandbox Code Playgroud)

这不会编译,因为

类SomeClass,不带模板参数

没有模版参数,没有办法/解决方法使用它,有点使该类的枚举成为全局类,因此它不依赖于该参数。

不是我不能输入它们,而是它们可能又长又复杂,代码将更难阅读,在这里我不能使用诸如auto之类的东西。(我是模板的新手,如果这个问题很me脚,抱歉。)

c++ templates

4
推荐指数
1
解决办法
1183
查看次数

可选的嵌套类和 is_constructible 之间奇怪的交互

在处理现实项目时,我偶然发现了某些(某些版本)编译器的奇怪行为。考虑以下类声明:

struct OptionalsStruct {
    struct InnerType {
        bool b{};
    };

    OptionalsStruct() = default;

    std::optional<InnerType> oInnerType;
};
Run Code Online (Sandbox Code Playgroud)

对于某些编译器,它OptionalStruct::InnerType不可构造的,但不可构造默认可构造的clang 1116GCC 10),对于其他一些编译器,它既不是不可构造的clang 910),更不用说clang 8如何看待整体事物。

我的问题是:这些行为是编译器错误,还是标准中的漏洞(我使用的是 C++17)?我在这里错过了什么吗?

c++ inner-classes type-traits c++17

4
推荐指数
1
解决办法
192
查看次数