使用using声明来创建类型的不可变版本是错误的,还是好的做法?
struct MutableA
{
int i;
float f;
};
using ImmutableA = const MutableA;
Run Code Online (Sandbox Code Playgroud)
对于指针或引用成员,像propagate_const这样的包装器将确保Immutable对象中的const安全性.
这样做的好处是将Mutable转换为Immutable类型(我推测)没有成本,并避免代码重复.
这是一个好习惯吗?这是错的吗 ?它没用吗?
如何使用new 1 using关键字声明函数类型?
我知道如何使用它来声明函数指针类型.例如,以下typedef:
typedef int (*int_to_int)(int);
Run Code Online (Sandbox Code Playgroud)
似乎等同于以下使用声明:
using int_to_int = int (*)(int);
Run Code Online (Sandbox Code Playgroud)
如何对以下非指针typedef执行相同操作:
typedef int (int_to_intf)(int);
Run Code Online (Sandbox Code Playgroud)
我的"删除typedef名称并将其放在using"算法后不起作用:
using int_to_intf_u = int ()(int); // nope, doesn't compile
Run Code Online (Sandbox Code Playgroud)
一个goldbolt链接.
1至少对于像我这样仍然将"新"定义为"在C++ 11中引入"的可怜灵魂.
我正在编写一个实用程序库,它由几个"包"组成.每个包中的类都包含在各种名称空间中.我已经知道如何通过在类声明结束时自动声明使用语句来简化情况(见下文),这将避免程序员在cpp文件中执行此操作.
namespace Utility
{
class String
{
// Class Implementation
};
}
using Utility::String;
Run Code Online (Sandbox Code Playgroud)
我的理解是,如果用户包含头String.h并且String在Utility中,那么程序员将希望使用String.显然,如果有外部类链包括一堆污染命名空间的文件,那么这可能会很糟糕,所以我想到如何将它变成#define.
namespace Utility
{
class String
{
// Class Implementation
};
}
#ifdef AUTO_DECLARE_NAMESPACE
using Utility::String;
#endif
Run Code Online (Sandbox Code Playgroud)
这样,想要这种扩展功能的程序员可以获得它.
这是一个好主意还是有什么我忽略的?
为什么gcc HEAD 10.0.0 20190和Clang HEAD 9.0.0这两个反对这个计划?
#include <iostream>
void g( int x )
{
std::cout << "Hello g( " << x << " )\n";
}
template <int N>
void g()
{
std::cout << "Hello g<N>( " << N << " )\n";
}
namespace N
{
using ::g;
}
void g( int x = 20 );
template <int N = 10>
void g();
int main()
{
N::g();
N::g<>();
}
Run Code Online (Sandbox Code Playgroud)
例如gcc发出错误
prog.cc: In function 'int main()': …Run Code Online (Sandbox Code Playgroud) 根据标准中的一些引用:
[over.match.funcs]/4
[...] 对于通过 using 声明引入派生类的非转换函数,为了定义隐式对象参数的类型,该函数被认为是派生类的成员。
并考虑以下代码:
#include <iostream>
struct Base {
void show(double) {
std::cout << "0" << std::endl;
}
};
struct Test :Base {
using Base::show; //#1
void show(double) { //#2
std::cout << "1" << std::endl;
}
};
int main() {
Test t;
t.show(1.2);
}
Run Code Online (Sandbox Code Playgroud)
根据我引用的标准,这意味着将类型的隐式对象参数Test作为 #1.
对于#1,声明将是show(Test&,double)。
对于#2,声明将是show(Test&,double)。
所以为了重载解析的目的,每个隐式转换序列 的 与 的#1没有区别#2, 的调用t.show(1.2)会模棱两可,但是#2调用,为什么?如果我遗漏了标准中的某些内容,请纠正我。
为什么在 C++ 的 using 声明语句中使用逗号分隔列表是一种不好的做法?
例如
using std::cout;
using std::cin;
using std::endl;
Run Code Online (Sandbox Code Playgroud)
被认为比代码更好
using std::cout,std::cin,std::endl;
Run Code Online (Sandbox Code Playgroud)
如果代码包含逗号分隔的 using 声明列表,一些编译器(例如 gcc)甚至会发出警告。
当然,最好的做法是对标识符使用完全限定的名称。
我有一个类,Tracker我在其中声明了一个别名
从Tracker.h:
class Tracker {
...
using ArgsMap = std::unordered_map<std::string, std::string>;
std::shared_ptr<ArgsMap> getArgsMapForTask(std::string task);
...
}
Run Code Online (Sandbox Code Playgroud)
在 .cpp 文件中,我定义了该函数:
#include Tracker.h
...
// ArgsMap here gives error: Use of undeclared identifier 'ArgsMap'
std::shared_ptr<ArgsMap> Tracker::getArgsMapForTask(std::string taskName)
{
ArgsMap a; // this gives no error, compiler recognizes ArgsMap
}
Run Code Online (Sandbox Code Playgroud)
如何ArgsMap在函数签名中使用?
c++ ×7
using ×2
alias ×1
api ×1
api-design ×1
c++11 ×1
c++17 ×1
immutability ×1
namespaces ×1
signature ×1