当我从继承列表中选择特定的隐藏函数时,如何使用noexcept?

时间:2016-07-10 19:15:00

标签: c++ inheritance c++14

为了避免重复类似的函数定义,我使用了一个事实,即隐藏了具有相同名称的继承成员,并且可以使用特定的基类限定符来选择/区分:

#include <type_traits>

template<template<class, class> class CreatePolicy, class Base, class... Derived>
class factory : public CreatePolicy<Base, Derived>...
{
public:
    template
    <
        class T,
        std::enable_if_t
        <
            !std::is_same<Base, T>::value && std::is_base_of<Base, T>::value, int
        > = 0
    >
    std::unique_ptr<Base> create() noexcept( noexcept( CreatePolicy<Base, T>::create() ) )
    {
        return CreatePolicy<Base, T>::create();
    }
};

使用它看起来像这样:

#include <memory>
#include <cassert>

template<class Base, class Derived>
struct create_t
{
    auto create()
    {
        return std::make_unique<Derived>();
    }
};

struct base
{
    virtual void print() const noexcept
    {
        std::cout << "base\n";
    }
};

struct derived : public base
{
    virtual void print() const noexcept override
    {
        std::cout << "derived\n";
    }
};

int main()
{
    factory<create_t, base, derived> f;
    auto d = f.create<derived>();
    d->print();
}

虽然这在VC ++ 2015下编译,但由于noexcept create()的{​​{1}}规范,GCC5.1给出了这个错误:

..\main.cpp|20|error: cannot call member function 'auto
create_t<T>::create() [with T = derived]' without object|

如何进行编译?

2 个答案:

答案 0 :(得分:1)

调用基类的成员函数的语法Auto仅在成员函数体内有效。这特别排除了base_class::method(...)规范中出现的未评估上下文。然而,这些背景的美妙之处在于它们只是:没有评估。所以你可以以某种方式得到你的类的实例并调用该方法。执行此操作的标准方法是使用noexcept

std::declval

答案 1 :(得分:0)

std::unique_ptr<Base> create() noexcept( noexcept( std::declval<CreatePolicy<Base, T>&>().create() ) )

live example

您只能在方法体内获得隐式this->。 Msvc经常错误地模板扩展,所以除非另有证明,否则我会认定他们有罪。