小编sky*_*ack的帖子

[] <typename>(){}是一个有效的lambda定义吗?

我正在尝试使用lambdas和编译器,因为这里有另一个问题.
我刚刚意识到(并且确实非常正常)以下代码是有效的:

int main() {
    auto l = [](){};
    l.operator()();
}
Run Code Online (Sandbox Code Playgroud)

实际上标准说闭包类型有一个公共内联函数调用操作符等等,因此能够调用它是有意义的.

通过查看标准(以及工作草案)我无法解释的是,GCC(6.1)编译了以下代码段(clang 3.9没有):

int main() {
    auto l = []<typename>(){};
    l.operator()<void>();
}
Run Code Online (Sandbox Code Playgroud)

没有警告,没有错误.它是有效的代码还是被编译器拒绝?

c++ lambda gcc clang language-lawyer

23
推荐指数
1
解决办法
1181
查看次数

unique_ptr的static_pointer_cast替代方案

我知道使用static_pointer_castwith unique_ptr会导致所包含数据的共享所有权.
换句话说,我想做的是:

unique_ptr<Base> foo = fooFactory();
// do something for a while
unique_ptr<Derived> bar = static_unique_pointer_cast<Derived>(foo);
Run Code Online (Sandbox Code Playgroud)

无论如何,这样做的结果是两个unique_ptr不应该同时存在,所以它只是被禁止.
是的,绝对有道理,这就是为什么不存在static_unique_pointer_cast确实存在的原因.

到目前为止,在我想存储指向这些基类的指针的情况下,但我还需要将它们转换为某些派生类(例如,想象一下涉及类型擦除的场景),我使用了shared_ptrs因为我的'如上所述.

无论如何,我猜测是否有替代方案可以shared_ptr解决这样的问题,或者在这种情况下它们是否真的是最佳解决方案.

c++ casting shared-ptr unique-ptr c++11

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

如何使C++ ADL查看模板的所有实例?

我正在关注如何在C++教程中实现一个常量表达式计数器我正在尝试修复C++ 14没有宏的反射,标记或外部工具..谈话限制.

本教程的基本思想是:

template<int N>
struct flag {
  friend constexpr int adl_flag (flag<N>);
};

template<int N>
struct writer {
   friend constexpr int adl_flag (flag<N>) { return N; }
   static constexpr int value = N;
};

template<int N, class = char[noexcept(adl_flag(flag<N> ()))?+1:-1]>
int constexpr reader (int, flag<N>) { return N; }

template<int N>
int constexpr reader (float, flag<N>, int R = reader (0, flag<N-1>())) { return R; }

int constexpr reader (float, flag<0>) { return …
Run Code Online (Sandbox Code Playgroud)

c++ template-meta-programming constexpr c++11 c++14

22
推荐指数
1
解决办法
728
查看次数

使用static_assert时如何避免关于无返回表达式的警告?

为了方便起见,我使用了两个库,并在它们使用的某些类型/结构之间编写了一个转换器.

template<typename T>
struct unsupportedType : std::false_type
{};

template<typename T>
FormatB getFormat()
{
    static_assert(
        unsupportedType<T>::value, "This is not supported!");
}

template<>
FormatB getFormat<FormatA::type1>()
{
    return FormatB(//some parameters);
}

template<>
FormatB getFormat<FormatA::type2>()
{
    return FormatB(//some other parameters);
}
Run Code Online (Sandbox Code Playgroud)

现在由于unsupportedType结构,编译器不会立即看到断言将始终失败,因此如果未在某处调用非专用版本,则不会抛出编译错误.但是,编译器因此也不知道返回语句之后static_assert是不必要的.我不只是想在断言之后放置一个任意的return语句来消除警告.

问题:什么是清除警告的干净方法?

c++ templates compiler-warnings

20
推荐指数
3
解决办法
1157
查看次数

结构化绑定:当某些内容看起来像引用并且行为类似于引用时,但它不是引用

昨天我在SO上看到了一个关于结构化绑定的有趣问题.
我们可以总结如下.请考虑以下示例代码:

#include <tuple>
#include <type_traits>

int main() {
    auto tup = std::make_tuple(1, 2);
    auto & [ a, b ] = tup;
    // the following line won't compile for a isn't a reference
    // static_assert(std::is_reference_v<decltype(a)>);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下decltype(a)int(可能),因为这种子弹(工作草案):

if e是一个未加括号的id-expression,用于命名结构化绑定[...],decltype(e)是结构化绑定声明规范中给出的引用类型

是@Curious在评论中为感兴趣的人提供的wandbox片段.它表明实际上a不是参考,仅此而已.
到目前为止好于原来的问题,OP问为什么它int,而不是int &标准说,看上去像一个可以接受的答案.

无论如何,我想知道委员会为何如此决定.在一天结束时,a引用元组中的元素,我可以通过修改该元素a.换句话说,声明a看起来像一个引用,它的行为类似于引用,但它不是引用.

我可以忍受这个,但我想知道背后的原因是什么.为什么decltype(a)不能简单int &?亵渎者可以理解是否有一个有意义的理由?

c++ language-lawyer c++17 structured-bindings

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

std ::成员函数指针的映射?

我需要实现std::map<std::string, fn_ptr>对.函数指针是指向拥有映射的同一类的方法的指针.我们的想法是直接访问方法,而不是实现交换机或等效方法.

(我std::string用作地图的键)

我对C++很陌生,所以有人会发布一些伪代码或链接来讨论用函数指针实现一个映射吗?(指向拥有地图的同一个类所拥有的方法的指针)

如果您认为我的问题有更好的方法,也欢迎提出建议.

c++ stl

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

内联变量是否跨越边界是唯一的?

这是对这个问题的跟进.
如答案评论中所述:

内联变量具有以下属性: - 在每个转换单元中具有相同的地址.[...]通常您通过在cpp文件中定义变量来实现这一点,但是使用内联说明符,您只需在头文件中声明/定义变量,并且使用此内联变量的每个转换单元都使用完全相同的对象.

而且,从答案本身来说:

虽然该语言不保证(甚至提及)在跨共享库边界使用此新功能时会发生什么,但它确实可以在我的计算机上运行.

换句话说,当涉及共享库时,不清楚内联变量是否保证跨边界是唯一的.有人在经验证明它可以在某些平台上运行,但它不是一个正确的答案,它可能只是破坏其他平台上的一切.

内联变量在跨越边界使用时是否有任何保证,或者它只是一个我不应该依赖的实现细节?

c++ shared-libraries language-lawyer c++17 inline-variable

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

void(),逗号运算符(运算符)和不可能(?)重载

考虑以下结构:

struct S {};
Run Code Online (Sandbox Code Playgroud)

在C++ 14中,以下定义是有效的:

constexpr auto f() { return S{}, 'c'; }
Run Code Online (Sandbox Code Playgroud)

以及以下一个:

constexpr auto f() { return S{}, void(); }
Run Code Online (Sandbox Code Playgroud)

现在,请考虑以下涉及两个定义中的第一个的工作代码段:

#include<type_traits>

struct S {};

constexpr int operator,(S, char) { return 42; }
constexpr auto f() { return S{}, 'c'; }

int main() {
    constexpr int i{f()};
    static_assert(i == 42, "!");
    static_assert(std::is_same<decltype(f()), int>::value, "!");
}
Run Code Online (Sandbox Code Playgroud)

说来不是技术上的,逗号运算符的重载拦截了这对,S{}, 'c'并返回一个整数,正如在main函数中正确验证的那样.

现在,假设我想对第二个定义做同样的事情f:

constexpr auto f() { return S{}, void(); }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,逗号运算符应截取表单 …

c++ operator-overloading void comma-operator language-lawyer

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

构造函数,模板和非类型参数

我有一个类必须依赖于int模板参数的某些原因.
出于同样的原因,该参数不能成为类的参数列表的一部分,而是它的构造函数的参数列表的一部分(当然,模板化).

这里出现了问题.
也许我错过了一些东西,但是我看不到向构造函数提供这样一个参数的简单方法,因为它不能推断也不能明确指定.

到目前为止,我发现了以下替代方案:

  • 将上述参数放入类的参数列表中

  • 创建工厂方法或工厂函数,可以作为示例调用 factory<42>(params)

  • 为构造函数提供traits结构

我试图为最后提到的解决方案创建一个(不那么)最小的工作示例,以便更好地解释问题.
示例中的类不是自身的模板类,因为关键点是构造函数,无论如何真正的模板类是模板类.

#include<iostream>
#include<array>

template<int N>
struct traits {
    static constexpr int size = N;
};

class C final {
    struct B {
        virtual ~B() = default;
        virtual void foo() = 0;
    };

    template<int N>
    struct D: public B{
        void foo() {
            using namespace std;
            cout << N << endl;
        }

        std::array<int, N> arr;
    };

 public:
     template<typename T>
     explicit C(T) {
         b = new D<T::size>{};
     }

     ~C() …
Run Code Online (Sandbox Code Playgroud)

c++ templates constructor software-design traits

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

void({})中的{}是什么?

请考虑以下代码段:

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

什么是完全{}void({})
怎么解释?

当然,只是出于好奇.不管怎样,让我们​​走得更远.

请注意,GCC 6.1和clang 3.8都编译它没有错误(-std=c++14 -pedantic).
后者没有抱怨,前者显示警告:

警告:非类类型的list-initializer不能带括号

使用-pedantic-errors替代,GCC有错误而铛编译结束.

这种差异是否是两个编译器之一的错误?
我的意思是,它是否应该被接受的有效代码?

c++ gcc clang language-lawyer c++14

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