我有一个关于C++ 0x lambdas的问题.在我的代码中,知道给定类型是否是C++ 0x lambda表达式的类型将是有益的.举个例子:
struct foobar
{
void operator()()
{
}
};
auto lambda = []{};
typedef is_lambda < decltype(lambda) > ::type T; // T would be a true_type
typedef is_lambda < foobar > ::type T; // T would be a false_type
Run Code Online (Sandbox Code Playgroud)
将lambda表达式与函数和成员函数类型区分开来相当容易.函子是另一回事.
我在这里看到的问题是根据即将推出的C++ 0x标准定义lambda表达式; 唯一必须定义的是公共呼叫运营商.然而,对于仿函数也是如此; 测试调用操作符的存在是不足以区分lambda表达式和仿函数.此外,如果不存在仿函数的运算符,则会发生编译器错误,因为SFINAE不适用.这是什么时候发生的?仿函数的调用操作符可能是模板化的.所以,这样的代码:
typedef decltype(&T::operator()) call_type;
Run Code Online (Sandbox Code Playgroud)
将使用非模板化调用运算符的lambda表达式和仿函数,并为模板化调用运算符生成编译器错误.
我相信is_lambda < >只能使用内部编译器功能创建特征.你看到了如何实现这个特性的方法吗?
boost::exception 和 std::nested_exception 都解决了聚合上下文的问题,但方式不同。boost::exception 允许使用流操作符添加数据。std::nested_exceptions 允许使用 throw_with_nested() 向原始异常添加嵌套异常。
我现在想知道每种方法的优缺点。我通常喜欢尽可能地坚持标准的东西,但是有没有一个令人信服的理由选择 boost::exception 而不是嵌套异常?
注意:这不是使用字符串来选择switch-case块中的执行路径.
C++中的一个常见模式是使用switch-case块将整数常量转换为字符串.这看起来像:
char const * to_string(codes code)
{
switch (code)
{
case codes::foo: return "foo";
case codes::bar: return "bar";
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我们使用的是C++,因此使用std :: string更合适:
std::string to_string(codes code)
{
switch (code)
{
case codes::foo: return "foo";
case codes::bar: return "bar";
}
}
Run Code Online (Sandbox Code Playgroud)
然而,这会复制字符串文字.也许更好的方法是:
std::string const & to_string(codes code)
{
switch (code)
{
case codes::foo: { static std::string str = "foo"; return str; }
case codes::bar: { static std::string str = "bar"; return str; }
}
}
Run Code Online (Sandbox Code Playgroud)
但这有点难看,涉及更多的样板.
什么被认为是使用C++ 14解决这个问题最干净,最有效的解决方案?
我有一个这样的功能:
template <typename A, typename B>
void foo(const B & b)
{
...
}
Run Code Online (Sandbox Code Playgroud)
A应该是可选的;如果未在函数调用中明确定义,则应将其设置为B。目的是避免不必要的冗长代码:
int i;
// First variant: A is specified explicitly
foo<float>(i);
// Second variant: A is set to B implicitly
// This is because foo < int > (i) is unnecessarily verbose
foo(i);
Run Code Online (Sandbox Code Playgroud)
但是,我还没有找到一种方法来做到这一点。有人可以提出来吗?