我知道在C++ 11中我们现在可以using用来写类型别名,比如typedefs:
typedef int MyInt;
Run Code Online (Sandbox Code Playgroud)
从我的理解,相当于:
using MyInt = int;
Run Code Online (Sandbox Code Playgroud)
这种新语法来自于努力表达" template typedef":
template< class T > using MyType = AnotherType< T, MyAllocatorType >;
Run Code Online (Sandbox Code Playgroud)
但是,对于前两个非模板示例,标准中是否还有其他细微差别?例如,typedefs以"弱"方式进行别名.也就是说,它不会创建新类型,而只会创建新名称(这些名称之间隐含的转换).
它是否与using生成新类型相同或是否生成新类型?有什么不同吗?
我有两个带有 using 子句的基类
class MultiCmdQueueCallback {
using NetworkPacket = Networking::NetworkPacket;
....
}
class PlcMsgFactoryImplCallback {
using NetworkPacket = Networking::NetworkPacket;
....
}
Run Code Online (Sandbox Code Playgroud)
然后我声明一个类
class PlcNetwork :
public RouterCallback,
public PlcMsgFactoryImplCallback,
public MultiCmdQueueCallback {
private:
void sendNetworkPacket(const NetworkPacket &pdu);
}
Run Code Online (Sandbox Code Playgroud)
编译器然后标记对“NetworkPacket”的错误引用是不明确的“sendNetworkPacket(NetworkPacket &...”
现在,两个“使用子句”都解析为相同的底层类 Networking:NetworkPacket
事实上,如果我将方法声明替换为:
void sendNetworkPacket(const Networking::NetworkPacket &pdu);
Run Code Online (Sandbox Code Playgroud)
它编译得很好。
为什么编译器将每个 using 子句视为不同的类型,即使它们都指向相同的底层类型。这是标准规定的还是我们有编译器错误?
请参阅以下代码
struct A { using type = int; };
struct B : private A {};
struct C : B { using base_type = A; };
Run Code Online (Sandbox Code Playgroud)
所有的gcc 6.1,clang 3.8和msvc 2015更新3都拒绝编译它,因为A它不是一个可访问的名称,C因为它A是一个私有基础B.似乎gcc认为A是using base_type = A指默认构造函数A.msvc和clang似乎没有.
也许编译错误是由于继承触发的名称注入(因为修改using base_type = A为using base_type = ::A使所有编译器工作正常),但我想知道这个奇怪的错误是否是标准所说的.
更具体地说,
A::type,A只是一个类名(虽然gcc误解为一个函数名),它不是引入C 内部 A也不引入B.为什么这个名字被认为是私人的B?看看下面的代码:
struct A {
public:
virtual void f(){std::cout << "in A";};
};
struct B : A{
public:
virtual void f(){std::cout << "in B";};
int a;
};
struct C : B{
using A::f;
void test(){f();}
};
int main()
{
C c;
c.f(); // calls B::f, the final overrider
c.C::f(); // calls A::f because of the using-declaration
c.test(); //calls B::f
return 0;
}
Run Code Online (Sandbox Code Playgroud)
根据我的理解,B::f()in C应该隐藏使用声明A::f()带来的内容C; 如果是的话,为什么c.C::f()还要打电话A::f()?
如果c.C::f()调用A::f(),这应该意味着,在范围 …
根据c ++标准,以下程序是否格式良好或格式不正确?
namespace X { int i; }
namespace Y { using X::i; }
int main() { using X::i; using Y::i; }
Run Code Online (Sandbox Code Playgroud)
我用不同的编译器得到了不同的结果:
我不想修复这个程序让它在GCC上编译.我只是想知道c ++标准对此有何看法以及为什么三个编译器的行为不同.此外,我想如果这是任何这些编译器中的错误的结果.
在[namespace.udecl]/10中,您有以下示例:
namespace A {
int i;
}
namespace A1 {
using A::i;
using A::i; // OK: double declaration
}
void f() {
using A::i;
using A::i; // error: double declaration
}
Run Code Online (Sandbox Code Playgroud)
这个片段编译成clang.
在这个例子中:
template<class T>
struct S : T
{
using T::X;
};
Run Code Online (Sandbox Code Playgroud)
T::X是指部件上的从属名称X在T.如果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
这两种using关键字用法有什么区别:
using boost::shared_ptr;
Run Code Online (Sandbox Code Playgroud)
和
using namespace boost;
Run Code Online (Sandbox Code Playgroud) 考虑以下程序.根据c ++标准(参考所需标准的相关部分)是否格式良好:
namespace X { extern int i; }
namespace N { using X::i; }
int N::i = 1;
int main() {}
Run Code Online (Sandbox Code Playgroud)
我为不同的编译器得到了不同的结果.我正在试图弄清楚我应该为哪个编译器提交错误报告:
Clang:给出以下编译器错误:名称空间'N'中没有名为'i'的成员
GCC和Visual C++编译它没有错误.
为了比较,下面给出了所有三个编译器的编译器错误:
namespace X { void f(); }
namespace N { using X::f; }
void N::f() {};
int main() {}
Run Code Online (Sandbox Code Playgroud) 如果派生类定义了相同的名称,派生类将隐藏基类的重载名称,但我们总是可以使用using-declaration引入该重载集:
template <class BASE>
class A : public BASE
{
public:
using BASE::some_method;
void some_method();
}
Run Code Online (Sandbox Code Playgroud)
但是如果我从可变参数基类引入所有重载集呢?我可以写这样的东西吗?
template <class... BASES>
class A : public BASES...
{
public:
using BASES::some_method...;
void some_method();
}
Run Code Online (Sandbox Code Playgroud)
我考虑过使用一个帮助类:
template <class... BASES>
struct helper;
template <>
struct helper<> {};
template <class OnlyBase>
struct helper<OnlyBase> : OnlyBase
{
using OnlyBase::some_method;
};
template <class Base1, class... OtherBases>
struct helper<Base1, OtherBases> : public Base1, public helper<OtherBases...>
{
using Base1::some_method;
using helper<OtherBases...>::some_method;
};
Run Code Online (Sandbox Code Playgroud)
它确实有效.但它需要大量的输入(当然我可以使用宏,但我尽可能尝试使用c ++的编译时功能),当我想引入更多方法时,我必须在那段代码中做出很多改变.
一个完美的答案是一个简单的语法,但如果没有,我将使用帮助类.
c++ inheritance overloading using-declaration variadic-templates
c++ ×10
c++11 ×2
namespaces ×2
c++14 ×1
declaration ×1
definition ×1
inheritance ×1
name-lookup ×1
overloading ×1
templates ×1
typedef ×1