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)
istest
可以通过一个静态断言(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;