相关疑难解决方法(0)

什么是"表达SFINAE"?

http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx上,VC++团队正式声明他们尚未实现C++ 11核心功能"Expression SFINAE".但是,从http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html复制的以下代码示例将被VC++编译器接受.

例1:

template <int I> struct A {};

char xxx(int);
char xxx(float);

template <class T> A<sizeof(xxx((T)0))> f(T){}

int main()
{
    f(1);
}
Run Code Online (Sandbox Code Playgroud)

例2:

struct X {};
struct Y 
{
    Y(X){}
};

template <class T> auto f(T t1, T t2) -> decltype(t1 + t2); // #1
X f(Y, Y);  // #2

X x1, x2;
X x3 = f(x1, x2);  // deduction fails on #1 (cannot add X+X), calls #2
Run Code Online (Sandbox Code Playgroud)

我的问题是:什么是"表达SFINAE"?

c++ templates sfinae visual-c++ c++11

56
推荐指数
1
解决办法
1万
查看次数

'auto f(params) - > decltype(...,void())'中的'void()'有什么作用?

我发现这里的代码看起来像这样:

auto f(T& t, size_t n) -> decltype(t.reserve(n), void()) { .. }
Run Code Online (Sandbox Code Playgroud)

在我阅读的所有文档中,我被告知decltype签名为:

decltype( entity )

要么

decltype( expression )

任何地方都没有第二个论点.至少这是cppreference所指出的.这是第二个参数decltype吗?如果是这样,它会做什么?

c++ decltype sfinae c++11 trailing-return-type

53
推荐指数
1
解决办法
3142
查看次数

什么是带有两个参数的decltype?

编辑,为了避免混淆:decltype接受两个参数.看到答案.

以下两个结构可用于T在编译期间检查类型上成员函数的存在性:

// Non-templated helper struct:
struct _test_has_foo {
    template<class T>
    static auto test(T* p) -> decltype(p->foo(), std::true_type());

    template<class>
    static auto test(...) -> std::false_type;
};

// Templated actual struct:
template<class T>
struct has_foo : decltype(_test_has_foo::test<T>(0))
{};
Run Code Online (Sandbox Code Playgroud)

我认为这个想法是在检查成员函数的存在时使用SFINAE,因此如果p->foo()无效,则只test返回返回的省略号版本std::false_type.否则,第一个方法被定义T*并将返回std::true_type.实际的"切换"发生在第二个类中,它继承自返回的类型test.与不同的方法相比,这看起来更聪明,更"轻巧" is_same.

decltype与两个参数第一次看令我感到诧异,因为我认为这只是得到一个表达式的类型.当我看到上面的代码时,我认为它类似于"尝试编译表达式并始终返回第二种类型.如果表达式无法编译则失败"(所以隐藏此专业化; SFINAE).

但:

然后我想我可以使用这个方法来编写任何"is valid expression"检查器,只要它依赖于某种类型T.例:

...
    template<class T>
    static auto test(T* p) -> decltype(bar(*p), std::true_type());
...
Run Code Online (Sandbox Code Playgroud)

http://ideone.com/dJkLPF

这一点,所以我想,将返回 …

c++ decltype sfinae type-traits c++11

43
推荐指数
2
解决办法
6725
查看次数

使用decltype/SFINAE检测操作员支持

(有些)过时的文章探讨了decltype与SFINAE一起使用的方法,以检测某种类型是否支持某些运算符,例如==<.

以下是检测类是否支持<运算符的示例代码:

template <class T>
struct supports_less_than
{
    static auto less_than_test(const T* t) -> decltype(*t < *t, char(0))
    { }

    static std::array<char, 2> less_than_test(...) { }

    static const bool value = (sizeof(less_than_test((T*)0)) == 1);
};

int main()
{
    std::cout << std::boolalpha << supports_less_than<std::string>::value << endl;
}
Run Code Online (Sandbox Code Playgroud)

这输出true,因为当然std::string支持<操作员.但是,如果我尝试将它与支持<运算符的类一起使用,我会收到编译器错误:

error: no match for ‘operator<’ in ‘* t < * t’
Run Code Online (Sandbox Code Playgroud)

所以SFINAE不在这里工作.我在GCC 4.4和GCC …

c++ decltype sfinae c++11

15
推荐指数
3
解决办法
6816
查看次数

为什么这个代码快速的char*?

Sutter在1:15:26的演讲中,它呈现了如下代码,

class employee{
 std::string name_;

public:
template<class String, class=
 std::enable_if_t< !std::is_same<std::decay_t<String>, std::string>::value > >
void set_name(String && name)
   noexcept(std::isnothrow_assignable<std::string &, String>::value)
  {
    name_ = std::forward<String>(name);
  }
}
Run Code Online (Sandbox Code Playgroud)

我知道std::forward如果name是左值,name_将如何工作,将得到复制构造; 如果name是右值,name_将构造移动.但是在幻灯片中它还说Optimized to steal from rvalues (and more),还有什么呢?

后来它表明这个代码似乎是所有四个实现中最快的,特别是因为char *,任何人都有耐心去理解这些代码并解释什么是更优化以及为什么它是最快的,特别是在这种情况下char *

c++ c++11

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