c – lambda可以有“C”连接吗?

前端之家收集整理的这篇文章主要介绍了c – lambda可以有“C”连接吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这个标题或多或少地说了一切.我有以下一点
代码
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>

struct xloper12;

class Something
{
public:
    std::string asString() const;
};
extern std::vector<Something> ourSomethings;

class ExcelOutputLoader
{
public:
    void load( std::vector<std::string> const& value );
    xloper12* asXloper() const;
};

extern xloper12* ProcessException( std::string const& functionName );

extern "C" __declspec(dllexport) xloper12*
getSomethingList()
{
    try {
        std::vector<std::string> results;
        results.reserve( ourSomethings.size() );
        std::transform(
            ourSomethings.begin(),ourSomethings.end(),std::back_inserter(results),[]( Something const& o ) { return o.asString(); } );
        ExcelOutputLoader out;
        out.load( results );
        return out.asXloper();
    } catch (...) {
        return ProcessException( "GetSomthing" );
    }
}

我用虚拟代替了大多数非标准头文件
声明;问题是在最后的功能(即是
旨在从Excel调用).基本上,编译时
与Visual Studios 2012,我得到以下警告:

falseWarning.cc(34) : warning C4190: '<Unknown>' has C-linkage specified,but re
turns UDT 'std::basic_string<_Elem,_Traits,_Alloc>' which is incompatible with C

        with
        [
            _Elem=char,_Traits=std::char_traits<char>,_Alloc=std::allocator<char>
        ]

(重复四次,好的措施).但据我所知
它,lambda定义了一个具有operator()成员的类,而不是
一个功能.和(§7.5/ 4)“C语言联动被忽略
确定课堂成员姓名的语言联系
和类成员函数函数类型“
意味着外部的“C”应该在lambda上被忽略.

这不是一件大事:这只是一个警告,它很容易工作
周围(有外部的“C”函数调用一个C函数
做实际工作).但我还是想知道:是吗
我根本就不了解lambda,或者
是开发Visual C的人不明白的.
(在后一种情况下,我很担心,因为可移植性不是
问题,我们已经开始深入使用lambda了.但如果
作者的编译器不明白,那我很担心.)

编辑:

还有一些测试.如果我写的东西像:

extern "C" __declspec(dllexport) void
funct1()
{
    extern std::string another();
}

我也得到警告.这一次,我会说这是对的.
另一个是命名空间范围中的一个函数,它被声明
在一个外部的“C”块中,所以应该有“C”链接.
(有意思的是,我也得到了一个警告
我可能被最烦人的解析问题咬伤了.该
extern应该足以让编译器实现
我没有试图定义一个局部变量.)

另一方面,如果我写的东西像:

extern "C" __declspec(dllexport) void
funct2()
{
    class Whatever
    {
    public:
        std::string asString() { return std::string(); }
    };
    std::string x = Whatever().asString();
}

没有警告.在这种情况下,编译器正确执行
忽略成员函数上指定的“C”链接.

这让我想知道一点.是编译器处理
lambda作为具有operator()函数的类(就像它)
应该),还是把它当作一个功能?看起来像这样
后者,这让我担心,如果没有其他微妙的
涉及到的问题,大概只有当有捕获时可见
(可能只在非常特殊的情况下).

解决方法

这似乎不符合标准.

5.1.2:

3 – […] The closure type is declared in the smallest block scope,class scope,or namespace scope that contains the corresponding lambda-expression. […]
5 – The closure type for a lambda-expression has a public inline function call operator […]
6 – The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that,when invoked,has the same effect as invoking the closure type’s function call operator.

7.5:

4 – […] In a linkage-specification,the specified language linkage applies to the function types of all function declarators,function names with external linkage,and variable names with external linkage declared within the linkage-specification. […] A C language linkage is ignored in determining the language linkage of the names of class members and the function type of class member functions. […]

因此,函数调用运算符或函数指针的转换函数都不具有C语言链接,因为它们是类成员函数;但是由于5.1.2p6没有指定转换函数返回的函数在哪里声明,所以它的类型可能具有C语言连接.

一方面,如果我们考虑7.5p4中的一个例子:

extern "C" {
  class X {
  // ...
  void mf2(void(*)()); // the name of the function mf2 has C++ language
                       // linkage; the parameter has type pointer to
                       // C function
  };
}

这表明对函数指针的转换将具有C函数的返回类型指针,只要C函数类型在转换声明内部声明或在extern“C”块中被声明为内联:

extern "C" {
  class Y {
    (*operator void())(); // return type pointer to C function
  };
}

另一方面,该功能需要与函数调用运算符具有相同的效果,如果C语言联动阻止它是不可能的;我们可以得出结论,该函数必须在外部“C”块之外声明,类似的是转换函数的返回类型.但这可能会对编译器作者造成额外的工作量.

猜你在找的C&C++相关文章