在.NET中有一个null引用,它在任何地方用来表示对象引用是空的,然后有DBNull数据库驱动程序(和其他几个)用来表示......几乎相同的东西.当然,这会产生很多混乱,转换例程必须被制作出来,等等.
那么为什么最初的.NET作者决定这样呢?对我来说没有任何意义.他们的文档也没有意义:
DBNull类表示不存在的值.例如,在数据库中,表行中的列可能不包含任何数据.也就是说,该列被认为根本不存在而不仅仅是没有值.DBNull对象表示不存在的列.此外,COM interop使用DBNull类来区分VT_NULL变量(表示不存在的值)和VT_EMPTY变量(表示未指定的值).
什么是关于"不存在的列"的废话?存在一列,它只是没有特定行的值.如果它不存在,我会尝试访问特定的单元格,而不是DBNull!我可以理解区分VT_NULL和之间的必要性VT_EMPTY,但是为什么不做一个COMEmpty类呢?这将是整个.NET框架中更适合的.
我错过了什么吗?任何人都可以解释为什么DBNull被发明以及它有助于解决的问题?
它看起来像它可能是,有(至少在C99),可以适用于长度修改int:%hhd,%hd,%ld和%lld指signed char,short,long和long long.甚至还有一个长度修饰符适用于double:%Lf均值long double.
问题是他们为什么省略float?按照模式,它可能是%hf.
C++ 14将允许创建模板化的变量.通常的例子是变量'pi',可以读取它以获得各种类型的数学常数π的值(3表示int;可能的最接近的值float等)
除此之外,我们可以通过将变量包装在模板化的结构或类中来实现此功能,这与类型转换如何混合?我看到一些重叠.
除了pi示例之外,它如何与非const变量一起使用?任何用法示例,以了解如何充分利用此类功能及其目的是什么?
要填充存储库的子模块,通常会调用:
git submodule init
git submodule update
Run Code Online (Sandbox Code Playgroud)
在这种用法中,git submodule init似乎只做一件事:填充.git/config已经存在的信息.gitmodules.
那是什么意思?
不能git submodule update简单地使用来自的信息.gitmodules?这样可以避免:
git submodule init); 和.gitmodules内容到.git/config).或者:
git submodule init我不知道(在这种情况下,请赐教!); 要不然git submodule init 可以在Git中弃用而没有任何伤害.以下哪一项是正确的?
考虑以下代码:
#include <utility>
namespace ns
{
struct foo
{
foo() : i(0) {}
int i;
private:
foo(const foo&); // not defined,
foo& operator=(const foo&); // non-copyable
};
void swap(foo& lhs, foo& rhs)
{
std::swap(lhs.i, rhs.i);
}
}
template <typename T>
void do_swap(T& lhs, T& rhs); // implementation to be determined
int main()
{
ns::foo a, b;
do_swap(a, b);
}
Run Code Online (Sandbox Code Playgroud)
在C++ 03中,这种实现do_swap将被视为"已损坏":
template <typename T>
void do_swap(T& lhs, T& rhs)
{
std::swap(lhs, rhs);
}
Run Code Online (Sandbox Code Playgroud)
通过明确指定std::,它禁止ns::swap …
所有学生都对 C++ using-directives的行为感到惊讶。考虑这个片段(Godbolt):
namespace NA {
int foo(Zoo::Lion);
}
namespace NB {
int foo(Zoo::Lion);
namespace NC {
namespace N1 {
int foo(Zoo::Cat);
}
namespace N2 {
int test() {
using namespace N1;
using namespace NA;
return foo(Zoo::Lion());
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
你可能认为test会叫NA的foo(Zoo::Lion); 但实际上它最终会调用N1's foo(Zoo::Cat)。
原因是这using namespace NA实际上并没有将名称NA带入当前范围;它带来他们到最小共同祖先的范围NA和N2,这是::。并且using namespace N1不会将名称N1带入当前 …
根据广义常量表达式 - 修订版5,以下是非法的.
constexpr int g(int n) // error: body not just ‘‘return expr’’
{
int r = n;
while (--n > 1) r *= n;
return r;
}
Run Code Online (Sandbox Code Playgroud)
这是因为所有'constexpr'函数都必须具有这种形式{ return expression; }.我看不出有任何理由需要这样做.
在我看来,唯一真正需要的是不读取/写入外部状态信息,传入的参数也是'constexpr'语句.这意味着对具有相同参数的函数的任何调用都将返回相同的结果,因此可以在编译时"知道".
我的主要问题是,它似乎只是强迫你做一些真正的回旋形式的循环,并希望编译器优化它,以便它对非constexpr调用同样快.
要constexpr为上面的例子写一个有效的,你可以这样做:
constexpr int g(int n) // error: body not just ‘‘return expr’’
{
return (n <= 1) ? n : (n * g(n-1));
}
Run Code Online (Sandbox Code Playgroud)
但是这很难理解,你必须希望编译器在使用违反要求的参数调用时处理尾递归const-expr.
该标准不允许这样的代码:
namespace Hello::World {
//Things that are in namespace Hello::World
}
Run Code Online (Sandbox Code Playgroud)
而是要求
namespace Hello { namespace World {
//Things that are in namespace Hello::World
}}
Run Code Online (Sandbox Code Playgroud)
理由是什么?这当时根本没有想到,还是有一个特定的原因不包括在内?
似乎第一个语法更直接地表达了应该在哪个命名空间中,因为声明模仿了以后代码中命名空间的实际使用.如果你不幸使用"哑"括号计算缩进工具,它也会减少缩进.
C++中隐藏规则背后的基本原理是什么?
class A { void f(int); }
class B : public A { void f(double); } // B::f(int) is hidden
Run Code Online (Sandbox Code Playgroud)
如果它是一个有意义的功能,我认为也应该可以隐藏功能而无需定义具有相同名称的新功能:如下所示:
class B : public A { hide void f(double); }
Run Code Online (Sandbox Code Playgroud)
但这是不可能的.
我不认为它简化了编译器的工作,因为编译器必须能够在显式使用指令时取消隐藏函数using:
class B : public A { using A::f; void f(double); } // B::f(int) NOT hidden
Run Code Online (Sandbox Code Playgroud)那么,怎么会有隐藏规则呢?
嗯,所有三个答案似乎都很好,并且显示了隐藏规则的不同理由.我不确定我应该接受哪个答案.
C++ 11给了我们std::add_const; 使用C++ 17,我们有了一个新的结构 - std::as_const().前者只是const在你提供的类型之前添加了一个.第二个是函数的正确(模板),而不是类型特征,它似乎也是一样 - 除了类型是rvalue-reference时,在这种情况下它不能被使用.
我不太明白提供的动机std::as_const().为什么我们除此之外还需要它std::add_const?