在我的项目上开发一系列POCO,并意识到其中一些不需要该using System;条款.
using <module>;在我的物品或项目上留下未使用的物品或尺寸是否有任何损失?
由于这个原因,我的类会变大,变慢还是膨胀,或者编译器/优化器是否足够智能来处理这个问题?
我的朋友给我看了以下代码
struct A {
virtual void f() = 0;
virtual void g() = 0;
};
struct AInternal : A {
virtual void f() { /* ... */ }
virtual void g() { /* ... */ }
};
Run Code Online (Sandbox Code Playgroud)
他正在使用AInternal一个实现大多数(如果不是全部A)的内部类.然后他继承了AInternal,但是因为他想要AInternal保持不可访问(因为它是一个实现细节),他继承了protected(以实现方式实现).他还做了什么是using使基类名称可A访问(它默认受保护,因为它也AInternal被继承保护)
struct C : protected AInternal {
using AInternal::A;
};
Run Code Online (Sandbox Code Playgroud)
实际上,这工作得很好(但是我们后来发现,它仍然保留了成员函数private- 只是基类被制作了public),但它只适用于GCC.它无法使基础A可访问.任何的想法?我们甚至可以让它破坏适用于Clang的代码
struct C : public AInternal {
protected:
using AInternal::A;
};
C …Run Code Online (Sandbox Code Playgroud) 以下程序是否符合c ++标准?
namespace X { class A; }
namespace Y { using X::A; class A {}; }
int main() {}
Run Code Online (Sandbox Code Playgroud)
我用不同的编译器得到了不同的结果:
我没有在我的程序违反的c ++标准中找到任何规则.
如果程序格式正确,为什么visual studio会出错?
如果程序格式不正确,那么c ++标准中的规则是否会违反,为什么gcc不会出错?
我不是想让我的程序编译.我只是想根据c ++标准找出它是否格式正确,以及为什么我测试的两个编译器表现不同.
我相信[namespace.memdef]/1的新措辞试图解释两个声明using M::g;和void g();命名空间之间的冲突X,但我无法理解这个新措辞与暗示冲突之间的关系.
命名空间中的
N声明(不包括嵌套作用域中的声明),其declarator-id为unqualified-id([dcl.meaning]),其class-head-name(Clause [class])或enum-head-name ([dcl] .enum])是一个标识符,或者其详细类型说明符 的格式为class-key attribute-specifier-seq opt identifier([dcl.type.elab]),或者是一个opaque-enum-declaration,声明(或重新声明)其不合格的身份或标识符作为成员N.[注意:模板的显式实例化([temp.explicit])或显式特化([temp.expl.spec])不会引入名称,因此可以在封闭名称空间的成员中使用unqualified-id声明如果主模板在内联命名空间中声明,则设置. - 尾注] [示例:Run Code Online (Sandbox Code Playgroud)namespace X { void f() { /* ... */ } // OK: introduces X?::?f() namespace M { void g(); // OK: introduces X?::?M?::?g() } using M::g; void g(); // error: conflicts with …
Microsoft编译器(Visual Studio 2017 15.2)拒绝以下代码:
#include <type_traits>
struct B
{
template<int n, std::enable_if_t<n == 0, int> = 0>
void f() { }
};
struct D : B
{
using B::f;
template<int n, std::enable_if_t<n == 1, int> = 0>
void f() { }
};
int main()
{
D d;
d.f<0>();
d.f<1>();
}
Run Code Online (Sandbox Code Playgroud)
错误是:
error C2672: 'D::f': no matching overloaded function found
error C2783: 'void D::f(void)': could not deduce template argument for '__formal'
note: see declaration of 'D::f'
Run Code Online (Sandbox Code Playgroud)
Clang也拒绝它:
error: no matching member …Run Code Online (Sandbox Code Playgroud) 我们在标准中有以下简单(并稍加修改以添加main和输出)示例:
struct A {
virtual void f()
{
cout << "A\n";
}
};
struct B : virtual A {
virtual void f()
{
cout << "B\n";
}
};
struct C : B, virtual A {
using A::f;
};
int main()
{
C c;
c.f(); // calls B?::?f, the final overrider
c.C::f();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
从中我们可以得出一个using A::f不存在重写的结论.但标准中的措辞是什么意思呢?以下是C++ 17草案([class.virtual] p2)中最终覆盖的措辞:
<...>类对象S的虚拟成员函数C :: vf是最终覆盖,除非其中S是基类子对象(如果有)的最派生类(4.5)声明或继承覆盖的另一个成员函数vf.在派生类,如果一个基类子对象的虚拟成员函数具有一个以上的最终超控器程序是非法的构造.
我无法找到"覆盖"实际意味着什么.如果没有定义并且我们将任何声明视为重载,那么我们应该将using声明视为重载,因为[namespace.udecl] p2说:
每个using声明都是声明和成员声明,因此可以在类定义中使用.
我理解标准使用声明的意图是不引入覆盖,但有人能指出我在Standardese中的实际引用吗?这是第一部分,现在是第二部分
请考虑以下代码:
#include <iostream>
#include <string>
using std::cout;
class A …Run Code Online (Sandbox Code Playgroud) c++ overriding multiple-inheritance using-declaration language-lawyer
考虑使用 C++20 using-enum-declaration 的以下代码片段:
namespace A { enum A {}; };
using namespace A;
using enum A;
Run Code Online (Sandbox Code Playgroud)
gcc-trunk拒绝它:
<source>:4:12: error: reference to 'A' is ambiguous
4 | using enum A;
| ^
<source>:1:20: note: candidates are: 'enum A::A'
1 | namespace A { enum A {}; };
| ^
<source>:1:11: note: 'namespace A { }'
1 | namespace A { enum A {}; };
| ^
<source>:4:12: error: 'A' has not been declared
4 | using enum …Run Code Online (Sandbox Code Playgroud) 让我们考虑两个类,A并B使用以下接口:
class A {
public:
virtual void start() {} //default implementation does nothing
};
class B {
public:
void start() {/*do some stuff*/}
};
Run Code Online (Sandbox Code Playgroud)
然后是A公开的第三个类,它是公开的,因为它实现了这个"接口",B私下因为它的实现细节.
但是,在此特定实现中,start()只需要包含一个调用B::start().所以我想我可以使用快捷方式并执行以下操作:
class C: public A, private B {
public:
using B::start;
};
Run Code Online (Sandbox Code Playgroud)
并完成它,但显然它不起作用.所以我得using私有基本功能不起作用,以覆盖虚拟.由此,有两个问题:
start()函数具有完全相同的签名C,但编译器看起来很好,只有调用A::start().编辑:一些准确性:
C通过A指针操纵对象.B::start(),我特别想知道一个using声明是否确实可以"覆盖"一个虚拟,如果没有,这是如何允许这两个函数共存的.virtual为简单起见,我可能省略了一些像继承这样的东西.c++ overriding virtual-functions using-declaration private-inheritance
我正在尝试在我的程序中使用tuple,由于某种原因,我无法通过声明来简化调用using。例如:
#include <tuple>
using std::tuple;
...
Run Code Online (Sandbox Code Playgroud)
尝试编译时会引发错误:
error: no member named 'tuple' in namespace 'std'
Run Code Online (Sandbox Code Playgroud)
我可以将using声明用于其他事物(例如std::string、std::get等)。我想我已经将其范围缩小到编译器问题,但我无法控制我使用哪个编译器(大学服务器),并且我在网上找不到任何显示缺乏对此标头或任何内容的支持的内容。这是我的编译器信息:
$ clang++ -v
Apple LLVM version 7.3.0 (clang-703.0.31)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?这是它在其他地方工作的示例: http: //cpp.sh/5bofm
当我using这样使用时,为什么构造函数是公开继承的?
class Base {
int x;
public:
Base(int x);
};
class Derived : public Base {
using Base::Base;
};
Run Code Online (Sandbox Code Playgroud)
我现在可以这样做:
Derived d (2);
Run Code Online (Sandbox Code Playgroud)
我认为using声明可以看到它们所在的位置。在这里,它应该是私有的。
来自C++ 编程语言:
通过 using 声明带入派生类作用域的名称的访问权限由 using 声明的位置决定;
c++ ×9
overriding ×2
.net ×1
c# ×1
c++14 ×1
c++20 ×1
class ×1
constructor ×1
declaration ×1
inheritance ×1
llvm-clang ×1
name-lookup ×1
namespaces ×1
performance ×1
sfinae ×1