Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Is&;decltype(对象)::是否存在误用?_C++_C++11_Decltype - Fatal编程技术网

C++ Is&;decltype(对象)::是否存在误用?

C++ Is&;decltype(对象)::是否存在误用?,c++,c++11,decltype,C++,C++11,Decltype,我上过这样的课: class Test { public: bool bar(int &i, char c) // some arguments are passed by ref, some are by value {/*...*/} bool foo(/*...*/) {} }; 我不想重复调用bar1/bar2等,然后反复检查返回值,所以我编写了一个宏和变量模板来处理这些事情 #define help_macro(object, memfn, .

我上过这样的课:

class Test {
public:
    bool bar(int &i, char c) // some arguments are passed by ref, some are by value
    {/*...*/}
    bool foo(/*...*/)
    {}
};
我不想重复调用bar1/bar2等,然后反复检查返回值,所以我编写了一个宏和变量模板来处理这些事情

#define help_macro(object, memfn, ...) help_func(#object "." #memfn, \
        object, &decltype(object)::memfn, ##__VA_ARGS__)

template<class T, typename Func, typename... Args>
void help_func(char const * name, T &&object, Func memfn, Args&&... args)
{
    auto ret = (object.*memfn)(forward<Args>(args)...);
    cout<<name<<":\t"
        <<(ret ? "OK" : "Oops")  // maybe I'll throw an exception here  
        <<endl;
}
它可以在g++-4.7/Debian上运行,但ICC13.0/Win拒绝编译它(一条非常奇怪的错误消息)

main.cpp(37):错误:不允许使用类型名称
help_宏(t,bar,i,'a')
^
main.cpp(37):错误:应为a“”
help_宏(t,bar,i,'a')
^

我打开了C++11 for ICC,并确认ICC13支持可变模板和decltype
我是否使用不正确或是ICC的问题?

我认为原因是类测试中没有“bar”函数,但不确定,因为我没有访问此编译器的权限。但是,您发布的错误消息显示有人试图使用“bar”

以下是关于gcc和clang的工作

class Test {
public:
    bool bar1(int &i, char c) // some arguments are passed by ref, some are by value
    {return true;}
    bool bar2(int &i, char c)
    {return true;}
};

#define help_macro(object, memfn, ...) help_func(#object "." #memfn, \
        object, &decltype(object)::memfn, ##__VA_ARGS__)

template<class T, typename Func, typename... Args>
void help_func(char const * name, T &&object, Func memfn, Args&&... args)
{
    auto ret = (object.*memfn)(std::forward<Args>(args)...);
    std::cout<<name<<":\t"
        <<(ret ? "OK" : "Oops")  // maybe I'll throw an exception here
        <<std::endl;
}

int main()
{
    int i = 0;
    Test t;
    //help_macro(t, bar, i, 'a');
    help_macro(t, bar2, i, 'a');
}
类测试{
公众:
boolbar1(int&i,char c)//有些参数是通过ref传递的,有些是通过值传递的
{返回true;}
bool bar2(内部和内部,字符c)
{返回true;}
};
#定义help_宏(object,memfn,…)help_func(#object“.”memfn\
对象和decltype(对象)::memfn、###uuu VA_uargs_uu)
模板
void help_func(char const*name、T&&object、func memfn、Args&&Args)
{
auto-ret=(object.*memfn)(std::forward(args)…);

std::cout编辑:实际上费心测试我的理论,结果证明我是错的,在这种情况下,
decltype(t)
is
test
可以通过一个
静态断言(std::is\u same::value,“nota reference”)显示出来。

因此,ICC(或它使用的EDG前端)可能不支持在嵌套的名称说明符中使用
decltype
,这是由

使用
std::decay
确实会让ICC接受它,这也是一个有用的解决方法

原创,错误,回答

我认为ICC就在这里,
decltype(object)
实际上是
Test&
,引用类型不能有成员,所以
&decltype(t)::memfn
格式不正确

代码可以简化为:

struct Test {
    void foo() {}
};

int main()
{
  Test t;
  auto p = &decltype(t)::foo;
}
这是G++和Clang接受的,但ICC拒绝的,正确地说

您可以使用
std::remove_reference
std::decay

#include <type_traits>

// ...

Test t;
auto p = &std::decay<decltype(t)>::type::foo;
#包括
// ...
试验t;
自动p=&std::decay::type::foo;

我不确定,但我建议避免转发。您似乎没有检查参数,因此可以避免转发,只执行
\define help_macro(call,…)help_函数(#call,call(u VA_ARGS_u))
模板帮助_函数(const char*name,t&&ret){cout help_macro(t,bar,I,'a').你是说bar2,对吗?“测试”中没有“bar”(如错误消息中所示)这看起来像是要避免的黑客类型,如果你想保持可读性(由人类)。对不起,伙计们,这是我的错误。PS,我能在代码中使用吗?似乎没用。这是我第一篇关于stackoverflow的帖子:(嗨,@JanHudec谢谢你的建议,你的代码真的很清晰,很抱歉,这是个打字错误。我复制了我的代码并修改了它:(可能是主题外的,但是为什么
操作符不丢弃引用?隐式衰减有时会不受欢迎吗?好问题,我不知道答案。[expr.prim.general]特别是说“嵌套名称说明符中由decltype说明符表示的类型应该是类或枚举类型。”哦,实际上这是后C++11 DR,这也是相关的,并且允许
decltype(T)的更改::mem
是根据那个年代,C++11的后期更改是为了允许语法生成,缺陷报告另外规定不允许引用。因此,向前看,
std::decay
是一条路,实际使用每743的功能是一个坏主意,除非你手头有声明,而且是一个坏主意习惯。是的,我同意。在这个问题的具体例子中,
decltype(t)
不是引用,但在一般情况下可能是引用,因此使用
decay
remove\u reference
应该是无害的,或者让代码做正确的事情
#include <type_traits>

// ...

Test t;
auto p = &std::decay<decltype(t)>::type::foo;