标签: inheriting-constructors

C++ 11继承构造函数和访问修饰符

假设以下布局:

class Base
{
protected:
    Base(P1 p1, P2 p2, P3 p3);

public:
    virtual void SomeMethod() = 0;
}

class Derived : public Base
{
public:
    using Base::Base;

public:
    virtual void SomeMethod() override;
};
Run Code Online (Sandbox Code Playgroud)

我应该能够在Derived这里指定公共构造函数吗?VC++给出以下错误:

无法访问类'Derived'中声明的受保护成员
编译器已在此处生成'Derived :: Derived'[指向使用Base :: Base行]
请参阅'Derived'的声明

即它忽略了继承构造函数上方的访问修饰符.

这是该功能的限制吗?Base对于具有公共构造函数的类没有任何意义,因为它永远不能直接实例化(由于纯虚方法).

c++ visual-c++ c++11 inheriting-constructors

37
推荐指数
1
解决办法
1912
查看次数

在using-declaration中,依赖名称可以在模板替换后呈现给构造函数吗?

在这个例子中:

template<class T>
struct S : T
{
    using T::X;
};
Run Code Online (Sandbox Code Playgroud)

T::X是指部件上的从属名称XT.如果S<T>实例化为T = X:

struct X
{
    X(int) {}
};
...
S<X> s(42);
Run Code Online (Sandbox Code Playgroud)

using声明是否会成为继承构造函数?

Clang拒绝代码DEMO,而g ++接受它.

请注意,如果我们写:

using T::X::X;
Run Code Online (Sandbox Code Playgroud)

两个编译器都接受代码并将其视为继承构造函数.被using T::X允许通过标准成为继承,构造函数?

c++ templates using-declaration language-lawyer inheriting-constructors

18
推荐指数
1
解决办法
174
查看次数

继承 - 构造函数+非类型 - 非默认构造类型的初始化失败

我在我的项目中遇到以下错误:

error: use of deleted function ‘C::C(int)’ note: ‘C::C(int)’ is
implicitly deleted because the default definition would be ill-formed:
error: use of deleted function ‘M::M()’

这是我正在使用的代码:

struct M {
    M(int){}
    M() = delete;  // Allowing this would work.
};

struct B {
    B(int) {}
    B() = delete;
};

struct C : public B {
    using B::B;
    M n = {5};

    // C(int i) : B(i) {}  // Adding this would work
};

C c{1};
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么会这样?


很明显,语言愿意在继承的构造函数的末尾添加更多的初始化(因为它愿意调用默认的构造函数).显然,它愿意隐式地将对非默认构造函数(类初始化)的调用添加到显式定义的构造函数的末尾.但由于某种原因,我不明白,它不愿意同时做这两件事.

根据这个问题,完美转发不够完美,不应该在这里使用.

注意:在实际情况下,构造函数 …

c++ in-class-initialization c++11 inheriting-constructors

15
推荐指数
1
解决办法
182
查看次数

使用boost :: multiprecision :: mpz_int构造函数继承失败

我试图创建一个派生自的类,boost::multiprecision::mpz_int并让它继承基类构造函数:

#include <boost/multiprecision/gmp.hpp>

using namespace boost::multiprecision;

struct Integer:
    mpz_int
{
    using mpz_int::mpz_int;
};
Run Code Online (Sandbox Code Playgroud)

g ++ 4.9.0给出了以下错误:

main.cpp:8:20: error: 'template<class tag, class Arg1, class Arg2, class Arg3, class Arg4> Integer::Integer(const boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>&)' inherited from 'boost::multiprecision::number<boost::multiprecision::backends::gmp_int>'
     using mpz_int::mpz_int;
                    ^
main.cpp:8:20: error: conflicts with version inherited from 'boost::multiprecision::number<boost::multiprecision::backends::gmp_int>'
main.cpp:8:20: error: 'template<class Other, boost::multiprecision::expression_template_option ET> Integer::Integer(const boost::multiprecision::number<Backend, ExpressionTemplates>&)' inherited from 'boost::multiprecision::number<boost::multiprecision::backends::gmp_int>'
main.cpp:8:20: error: conflicts with version inherited from 'boost::multiprecision::number<boost::multiprecision::backends::gmp_int>'
main.cpp:8:20: error: 'template<class Other, boost::multiprecision::expression_template_option ET> Integer::Integer(const boost::multiprecision::number<Backend, …
Run Code Online (Sandbox Code Playgroud)

c++ boost language-lawyer c++11 inheriting-constructors

13
推荐指数
1
解决办法
511
查看次数

C++在继承构造函数中使用带有typename的声明

在阅读这个问题时,我发现了一个奇怪的观点:

template <typename T>
class Subclass : public Baseclass<T>
{
public:
    using typename Baseclass<T>::Baseclass;
    //    ^^^^^^^^
};
Run Code Online (Sandbox Code Playgroud)

既然typename,Baseclass<T>::Baseclass应该注入类名,而不是构造函数.据我所知,情况与此相同:

template <typename T>
class Base
{
public:
    typedef short some_type;
};

template <typename T>
class Sub : public Base<T>
{
public:
    using typename Base<T>::some_type;
};
Run Code Online (Sandbox Code Playgroud)

为了确保,我写了一个测试代码.

#include <iostream>

template <typename T>
class Base
{
public:
    Base() { std::cout << "A::A()\n"; }
    Base(int) { std::cout << "A::A(int)\n"; }
    Base(const char *) { std::cout << "A::A(const …
Run Code Online (Sandbox Code Playgroud)

c++ typename using-declaration language-lawyer inheriting-constructors

13
推荐指数
1
解决办法
857
查看次数

noexcept,继承构造函数和无效使用实际完成的不完整类型

我不确定这是GCC编译器的错误还是预期的行为noexcept.
请考虑以下示例:

struct B {
    B(int) noexcept { }
    virtual void f() = 0;
};

struct D: public B {
    using B::B;
    D() noexcept(noexcept(D{42})): B{42} { }
    void f() override { }
};

int main() {
    B *b = new D{};
}
Run Code Online (Sandbox Code Playgroud)

如果noexcept删除它,它编译.
无论如何,正如在例子中,我从GCC v5.3.1得到了这个错误:

test.cpp:8:31: error: invalid use of incomplete type ‘struct D’
     D() noexcept(noexcept(D{42})): B{42} { }
                               ^
Run Code Online (Sandbox Code Playgroud)

据我所知,struct D不是一个不完整的类型,但继承构造函数涉及到语句,看起来编译器实际上考虑的是基本结构的完整性而B不是D.

这是预期的行为还是合法代码?

为清楚起见:

c++ language-lawyer noexcept c++11 inheriting-constructors

12
推荐指数
1
解决办法
442
查看次数

所有版本的GCC都与默认成员初始化器相媲美,它捕获了这个,并与继承的构造函数相结合

这个故事与我之前的问题类似.支持C++ 11的所有GCC版本都具有这种确切的行为.我找不到任何其他编译器与我的测试用例斗争.

测试用例:

struct BaseFooWrapper
{
    BaseFooWrapper(int qux)
    { }
};

struct Foo
{
    Foo(BaseFooWrapper & foo)
        : foo(foo)
    { }

    BaseFooWrapper & foo;
};

struct SomeFooWrapper : public BaseFooWrapper
{
    using BaseFooWrapper::BaseFooWrapper;


    Foo foo{*this};
};

int main()
{
    SomeFooWrapper wrapped_foo(1);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

住在godbolt.com上


这段代码用clang(3.4到4.0),icc(16,17),Visual C++(19.00.23506)编译.

如果我用手写版本替换构造函数继承,那么GCC开始编译代码:

struct BaseFooWrapper
{
    BaseFooWrapper(int qux)
    { }
};

struct Foo
{
    Foo(BaseFooWrapper & foo)
        : foo(foo)
    { }

    BaseFooWrapper …
Run Code Online (Sandbox Code Playgroud)

c++ gcc c++11 inheriting-constructors

10
推荐指数
1
解决办法
420
查看次数

继承构造函数和虚拟基类

我即将创建一个异常类层次结构,概念上看起来像这样:

#include <iostream>
#include <stdexcept>

class ExceptionBase : public std::runtime_error {
public: 
    ExceptionBase( const char * msg ) : std::runtime_error(msg) {}
};

class OperationFailure : virtual public ExceptionBase {
public: 
    using ExceptionBase::ExceptionBase;
};

class FileDoesNotExistError : virtual public ExceptionBase {
public: 
    using ExceptionBase::ExceptionBase;
};

class OperationFailedBecauseFileDoesNotExistError
    : public OperationFailure, FileDoesNotExistError {
public: 
    using ExceptionBase::ExceptionBase; // does not compile
};

int main() {
    OperationFailedBecauseFileDoesNotExistError e("Hello world!\n");

    std::cout << e.what();
}
Run Code Online (Sandbox Code Playgroud)

所有构造函数应该与ExceptionBase类的构造函数相同.派生的异常仅在类型上有所不同,否则没有添加的功能.上面代码中提到的最后一个异常类型也应该有这些构造函数.这是否可以使用C++ 11标准的继承构造函数功能?如果那是不可能的:还有什么选择?

(顺便说一句:在上面的代码中的类OperationFailureFileDoesNotExistError.没有用gcc 4.8编译,但铿锵3.4显然,海湾合作委员会拒绝为虚拟基础继承构造函数这将是有趣的,知道谁在这里两种编译器拒绝了类OperationFailedBecauseFileDoesNotExistError …

c++ virtual-inheritance c++11 inheriting-constructors

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

通过派生类构造函数继承访问自己的私有构造函数

考虑

struct B {
    void f();
private:
    B(int, int = 0);
};
struct D : B { using B::B; };
void B::f() {
    auto a = D{0};
    auto b = D(0);
    auto c = D(0, 0);
    D x{0};
    D y(0);
    D z(0, 0);
}
Run Code Online (Sandbox Code Playgroud)

GCC 接受(从 7.1 开始;以前拒绝所有)。Clang 接受bandxyz但拒绝aand c。MSVC 在 C++14 模式下拒绝所有,但在 C++17 模式下接受所有。

哪些编译器是正确的?C++14 和 C++17 之间的规则是否发生了变化——如果是这样,为什么在 C++14 中B::f不允许访问它自己的构造函数(命名为 via D)?为什么 Clang 只接受(函数式)强制转换 atb而不是列表初始化 at …

c++ crtp language-lawyer inheriting-constructors c++17

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

默认情况下是继承构造函数noexcept(true)吗?

在这里我发现:

默认情况下,继承构造函数都是noexcept(true),除非它们需要调用noexcept(false)函数,在这种情况下这些函数是noexcept(false).

这是否意味着在下面的示例中,继承的构造函数是noexcept(true),即使它已经noexcept(false)在基类中显式定义,或者它被认为是一个函数是noexcept(false)被调用?

struct Base {
    Base() noexcept(false) { }
};

struct Derived: public Base {
    using Base::Base;
};

int main() {
    Derived d;
}
Run Code Online (Sandbox Code Playgroud)

c++ constructor noexcept c++11 inheriting-constructors

5
推荐指数
1
解决办法
352
查看次数

在模板派生类中使用类型别名继承构造函数

请参见以下代码:

struct base {};

template <class T>
struct derived : T {
  using base_type = T;
  using base_type::T;
};

int main()
{
  derived<base> x;
}
Run Code Online (Sandbox Code Playgroud)

GCC接受此代码,但是Clang和MSVC拒绝它。谁是正确的,为什么?

c++ language-lawyer c++11 inheriting-constructors

4
推荐指数
1
解决办法
119
查看次数

java中构造函数的继承

每当在任何派生类中调用任何构造函数时,任务只能通过最终隐式或显式地调用基类构造函数来完成(如果我在这里错了,请纠正我).

因为我们打算创建派生类的实例,但是因为最后调用了基类构造函数.

那么,尽管调用了基类的构造函数,如何构造派生类的实例?

java class-constructors inheriting-constructors

2
推荐指数
1
解决办法
548
查看次数