小编Gen*_*yev的帖子

自动类型扣除可能导致转换错误?

我有一个非常简单的解析器规则(对于AX),如下所示:

auto space = axe::r_lit(' ');
auto spaces = space & space & space;
Run Code Online (Sandbox Code Playgroud)

最后一行在VC2010中编译并按预期工作,但在gcc 4.6中给出了一个奇怪的错误:

parsers.cpp:68:34: error: conversion from 
'axe::r_and_t<
    axe::r_and_t<axe::r_char_t<char>&, axe::r_char_t<char>&>, 
    axe::r_char_t<char>&
>' to non-scalar type 
'axe::r_and_t<
    axe::r_and_t<axe::r_char_t<char>&, axe::r_char_t<char>&>&, 
    axe::r_char_t<char>&
>' requested
Run Code Online (Sandbox Code Playgroud)

我想知道,它是否是gcc中的(已知)错误,以及是否有可能通过auto声明获得转换错误.推导出的类型不auto应该总是与初始化器完全相同吗?

AX 重载运算符&像这样:

template<class R1, class R2>
r_and_t<
    typename std::enable_if<
       is_rule<typename std::remove_reference<R1>::type>::value, R1>::type, 
    typename std::enable_if<
       is_rule<typename std::remove_reference<R2>::type>::value, R2>::type
>
operator& (R1&& r1, R2&& r2)
{
    return r_and_t<R1, R2>(std::forward<R1>(r1), std::forward<R2>(r2));
}
Run Code Online (Sandbox Code Playgroud)

我无法将问题简化为一个简短的测试用例,不幸的是每次我尝试用简单的例子来编译它.

c++ g++ c++11

9
推荐指数
1
解决办法
602
查看次数

模板专业化的朋友声明失败

以下包含好友声明的代码失败并显示错误(请参阅http://ideone.com/Kq5dy):

template<class T> void foo() {}

template<typename T>
class A {
   void foo();
   friend void foo<T>(); // error: variable or field 'foo' declared void
};

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

如果朋友声明和成员函数声明的顺序颠倒了,那么代码编译没有问题(参见http://ideone.com/y3hiK):

template<class T> void foo() {}

template<typename T>
class A {
   friend void foo<T>();
   void foo();
};

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

如果朋友声明不包含模板专业化,则不会发生这种情况:非模板朋友可以,以及模板朋友.在模板专门化中使用限定名称也允许编译代码.我的问题是为什么第一个例子失败了?似乎编译器在朋友声明点查找类范围中的名称,仅用于模板专业化?标准中的哪个行为被指定?

c++ templates friend language-lawyer name-lookup

8
推荐指数
1
解决办法
1873
查看次数

从lambda调用函数时的查找规则是什么?

以下示例演示了我在VC++ 2010中遇到的问题:

class Foo
{
    template<class T>
    static T foo(T t) { return t; }

public:
    void test()
    {
        auto lambda = []() { return foo(1); }; // call to Foo::foo<int>
        lambda();
    }
};
Run Code Online (Sandbox Code Playgroud)

VC++产生:错误C3861 'foo'::标识符未找到

如果我将调用限定为foo:Foo::foo(1);那么这个例子会编译一个警告: 警告C4573:使用'Foo::foo'需要编译器捕获'this'但是当前的默认捕获模式不允许它

该标准对此案有何评价?应该找到不合格的名字吗?合格的名称是否需要捕获this

c++ c++11

6
推荐指数
1
解决办法
1411
查看次数

如何编写SFINAE来测试解析器规则?

我有一个测试类是否是解析器规则(AX解析器生成器库)的sfinae类.axe::is_rule<P>::value如果P满足解析器规则要求,则应评估为true.解析器规则必须具有以下成员函数之一,接受一对迭代器并返回axe::result<Iterator>:

template<class Iterator>
axe::result<Iterator> P::operator()(Iterator, Iterator);
Run Code Online (Sandbox Code Playgroud)

,或其专业化,或某些类型CharT的非模板

axe::result<CharT*> P::operator()(CharT*, CharT*);
Run Code Online (Sandbox Code Playgroud)

,或上面的const版本.从理论上讲,可能会有多个重载operator(),但在实践中operator(),对具有上述签名之一的单个测试就足够了.

不幸的是,目前的实施is_rule仅涉及一些但并非所有情况.有些不幸的课程没有通过is_rule测试:

#define AXE_ASSERT_RULE(T)\
    static_assert(axe::is_rule<typename std::remove_reference<T>::type>::value, \
    "type '" #T "' is not a rule");
Run Code Online (Sandbox Code Playgroud)

例如,以下不幸的类型未通过测试:

struct unfortunate 
{ 
   axe::result<const unsigned char*> 
   operator()(const unsigned char*, const unsigned char*); 
};

AXE_ASSERT_RULE(unfortunate);

// or same using lambda
auto unfortunate1 = [](const unsigned char*, const unsigned char*)
->axe::result<const unsigned char*> {};
AXE_ASSERT_RULE(decltype(unfortunate1));


typedef std::vector<char>::iterator vc_it;
struct unfortunate2 { axe::result<vc_it> operator()(vc_it, vc_it) …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

3
推荐指数
1
解决办法
255
查看次数

通过GetModuleHandle/LoadLibrary加载DLL并使用FreeLibrary

这是我的代码:

function GetProcedureAddress(var P: FARPROC; const ModuleName, ProcName: AnsiString): Boolean;
var
  ModuleHandle: HMODULE;
begin
  Result := False;
  ModuleHandle := GetModuleHandle(PAnsiChar(AnsiString(ModuleName)));
  if ModuleHandle = 0 then
    ModuleHandle := LoadLibrary(PAnsiChar(ModuleName)); // DO WE NEED TO CALL  FreeLibrary ?
  if ModuleHandle <> 0 then
  begin
    P := Pointer(GetProcAddress(ModuleHandle, PAnsiChar(ProcName)));
    if Assigned(P) then
      Result := True;
  end;
end;

function PathMakeSystemFolder(Path: AnsiString): Boolean;
var
  _PathMakeSystemFolderA: function(pszPath: PAnsiChar): BOOL; stdcall;
begin
  Result := False;
  if GetProcedureAddress(@_PathMakeSystemFolderA, 'shlwapi.dll', 'PathMakeSystemFolderA') then
    Result := _PathMakeSystemFolderA(PChar(Path));
end;
Run Code Online (Sandbox Code Playgroud)

如果使用LoadLibrary,我们需要调用FreeLibrary吗?或者当我的申请终止时,它的引用计数会自动递减?

windows delphi api winapi

3
推荐指数
1
解决办法
4825
查看次数

reinterpret_cast 的这种使用是否会引发未定义的行为?

基本思想是创建一个可变大小的数组,在构造时固定,并在单个分配单元中创建另一个类,以减少开销并提高效率。分配一个缓冲区来容纳数组,并使用另一个对象和新的放置来构造它们。为了访问数组和另一个对象的元素,使用了指针算术和reinterpret_cast。这似乎有效(至少在 gcc 中),但我对标准(5.2.10 Reinterpret Cast)的阅读告诉我这是一种未定义的行为。那是对的吗?如果是这样,有没有办法在没有UB的情况下实现这个设计?

完整的可编译示例在这里: http: //ideone.com/C9CCa8

// a buffer contains array of A followed by B, laid out like this
// | A[N - 1] ... A[0] | B |

class A
{
    size_t index;
//...
// using reinterpret_cast to get to B object
    const B* getB() const 
    { 
        return reinterpret_cast<const B*>(this + index + 1); 
    }
};

class B
{
    size_t a_count;
//...
    virtual ~B() {}
// using reinterpret_cast to get to the array member
    const A* …
Run Code Online (Sandbox Code Playgroud)

c++ arrays memory-management

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