相关疑难解决方法(0)

什么是完美转发设置器的正确`enable_if`约束?

Herb Sutter 回归基础!CppCon 上的现代C++演示要点讨论了传递参数的不同选项,并将其性能与写作/教学的简易性进行了比较."高级"选项(在所有测试的案例中提供最佳性能,但对大多数开发人员来说难以编写)是完美转发,给出了示例(PDF,第28页):

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::is_nothrow_assignable<std::string &, String>::value) {
        name_ = std::forward<String>(name);
    }
};
Run Code Online (Sandbox Code Playgroud)

该示例使用带转发引用的模板函数,模板参数String使用约束enable_if.然而,约束似乎是不正确的:似乎只有在String类型不是a 时才使用此方法std::string,这没有任何意义.这将意味着该std::string成员可以使用设置什么,但一个std::string值.

using namespace std::string_literals;

employee e;
e.set_name("Bob"s); // error
Run Code Online (Sandbox Code Playgroud)

我考虑的一个解释是,有一个简单的拼写错误,而且约束的目的是std::is_same<std::decay_t<String>, std::string>::value代替!std::is_same<std::decay_t<String>, std::string>::value.然而,这意味着setter不能使用,例如,const char *它显然是打算使用这种类型,因为这是在演示文稿中测试的案例之一.

在我看来,正确的约束更像是:

template <class String,
          class = std::enable_if_t<std::is_assignable<decltype((name_)),
                                                      String>::value>>
void set_name(String &&name) …
Run Code Online (Sandbox Code Playgroud)

c++ enable-if perfect-forwarding c++11 forwarding-reference

17
推荐指数
1
解决办法
1247
查看次数

使用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
查看次数

表达式是在decltype中执行,还是只是检查验证?

通过使用Expression SFINAE,您可以检测是否支持某些操作员操作.

例如,

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

我的问题是t.reserve(n)内部decltype被执行与否?

如果是,这是否意味着t.reserve(n)执行了两次,一次在内部decltype,另一次在函数体内?

如果没有,是否只是在编译期间检查验证?但是为什么它没有被执行,我认为逗号分隔表达式列表中的所有表达式都将被执行.

c++ templates sfinae c++11

6
推荐指数
1
解决办法
448
查看次数