使用C ++ 11类型特征提供替代的内联实现 [英] Using C++11 type traits to provide alternate inline implementations

查看:89
本文介绍了使用C ++ 11类型特征提供替代的内联实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码模式在模板化代码中同时使用两种可选实现总是可编译的特征时是否合理?

Is the following code pattern reasonable when using traits in templated code where both alternative implementations are always compilable?

阅读代码似乎比做其他恶作剧式的有条件编译更清晰(但是也许我对那些恶作剧还不够熟悉)。

Reading the code seems clearer than doing other shenanigans to conditionally compile (but then perhaps I'm just not familiar enough with those shenanigans).

template<typename T>
class X
{
    void do_something() noexcept(std::is_nothrow_copy_constructible<T>::value)
    {
        if (std::is_nothrow_copy_constructible<T>::value)
        {
            // some short code that assumes T's copy constructor won't throw
        }
        else
        {
            // some longer code with try/catch blocks and more complexity
        }
    }

    // many other methods
};

(增加的复杂性部分是为了提供强大的异常保证。)

(The added complexity is in part to provide the strong exception guarantee.)

我知道这段代码可以工作,但是可以合理地期望编译器消除常量错误分支并在noexcept情况下进行内联等(这里要简单得多)比另一种情况)?我希望在noexcept情况下能够像在主体中仅将第一个块作为主体编写方法那样高效(反之亦然,尽管我不太担心复杂的情况)。

I know this code will work, but is it reasonable to expect the compiler to eliminate the constant-false branches and do inlining etc for the noexcept case (where much simpler than the other case)? I'm hoping for something that would be as efficient in the noexcept case as writing the method with only that first block as body (and vice versa, though I'm less worried about the complex case).

如果这不是正确的方法,有人可以启发我使用推荐的语法吗?

If this isn't the right way to do it, can someone please enlighten me to the recommended syntax?

推荐答案


[...]对于noexcept情况(比其他情况简单得多),期望编译器消除常量错误分支并进行内联吗? / p>

[...] is it reasonable to expect the compiler to eliminate the constant-false branches and do inlining etc for the noexcept case (where much simpler than the other case)?

可以,但是我不会依靠它,因为您无法控制它。

It could be, but I wouldn't rely on that for you cannot control it.

如果要删除 if / else ,则可以 sfinae 返回类型并清理 noexcept 限定符。

例如:

If you want to remove the if/else, you can sfinae the return type and clean up the noexcept qualifier.
As an example:

template<typename T>
class X {
    template<typename U = T>
    std::enable_if_t<std::is_nothrow_copy_constructible<T>::value>
    do_something()
    noexcept(true)
    {}

    template<typename U = T>
    std::enable_if_t<not std::is_nothrow_copy_constructible<T>::value>
    do_something()
    noexcept(false)
    {}
};

缺点是您现在有两个成员函数模板。

不确定

The drawbacks are that you have now two member functions template.
Not sure it fits your requirements.

如果允许使用C ++ 17中的功能,则如果constexpr 这样的方法,您不必再将方法拆分为两个成员函数。

If you are allowed to use features from C++17, if constexpr is probably the way to go and you don't have to break your method in two member functions anymore.

另一种方法可能基于 tag-dispatching 您类型的无例外的性质。

例如:

Another approach could be based on tag-dispatching the noexceptness of your type.
As an example:

template<typename T>
class X {
    void do_something(std::true_type)
    noexcept(true)
    {}

    void do_something(std::false_type)
    noexcept(false)
    {}

    void do_something()
    noexcept(do_something(std::is_nothrow_copy_constructible<T>{}))
    { do_something(std::is_nothrow_copy_constructible<T>{}); }
};






我知道, sfinae 不是动词,但是对某些东西听起来很不错。


I know, sfinae is not a verb, but to sfinae something sounds just so good.

这篇关于使用C ++ 11类型特征提供替代的内联实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆