是否可以编写一个模板来改变行为,具体取决于是否在类上定义了某个成员函数?
这是我想写的一个简单例子:
template<class T>
std::string optionalToString(T* obj)
{
if (FUNCTION_EXISTS(T->toString))
return obj->toString();
else
return "toString not defined";
}
Run Code Online (Sandbox Code Playgroud)
所以,如果class T
已经toString()
确定的话,就使用它; 否则,它没有.我不知道怎么做的神奇部分是"FUNCTION_EXISTS"部分.
在Linux内核代码中,我发现了以下无法理解的内容.
struct bts_action {
u16 type;
u16 size;
u8 data[0];
} __attribute__ ((packed));
Run Code Online (Sandbox Code Playgroud)
代码在这里:http://lxr.free-electrons.com/source/include/linux/ti_wilink_st.h
零元素数据数组的需求和目的是什么?
12.8复制和移动类对象[class.copy]§31和§32说:
在具有类返回类型的函数的return语句中,当表达式是具有与函数返回类型相同的cv-unqualified类型的非易失性自动对象(函数或catch子句参数除外)的名称时,通过将自动对象直接构造到函数的返回值中,可以省略复制/移动操作
当满足或将满足复制操作的省略标准时,除了源对象是函数参数这一事实,并且要复制的对象由左值指定,重载决策选择复制的构造函数是首先执行,好像对象是由右值指定的.
因此我们可以写:
unique_ptr<int> make_answer()
{
unique_ptr<int> result(new int(42));
return result; // lvalue is implicitly treated as rvalue
}
Run Code Online (Sandbox Code Playgroud)
但是,我注意到g ++ 4.6.3也接受不是名称的左值,例如:
return (result);
return *&result;
return true ? result : result;
Run Code Online (Sandbox Code Playgroud)
相比之下,return rand() ? result : result;
不起作用.编译器的优化器是否会干扰语言语义?当我解释标准时,return (result);
不应该编译,因为(result)
它不是名称,而是带括号的表达式.我是对还是错?
Clang-3.2可以编译和代码按预期运行:
struct have_f { int f(int i) {return 10;} };
struct empty {};
template <class T>
struct outer {
T t;
// if T have f(), define outer_f()
template<class U=decltype(t.f(1))>
int outer_f(int i) { return t.f(i); }
};
int main() {
outer<have_f> o1;
outer<empty> o2;
// to silence unused var warning
return o1.outer_f(10) + sizeof(o2);
}
Run Code Online (Sandbox Code Playgroud)
任何版本的GCC拒绝:
t.cc:13:6: error: ‘struct empty’ has no member named ‘f’
int outer_f(int i) { return t.f(i); }
^
Run Code Online (Sandbox Code Playgroud)
谁是对的?Gcc还是Clang?
注意,有类似的问题,没有真正的答案.