假设我在头文件中声明了一个函数(或类,无所谓),它是命名空间foo的一部分:
namespace foo
{
void bar();
…
}
Run Code Online (Sandbox Code Playgroud)
很久以来,当我在cpp文件中定义函数时,我一直在重新打开命名空间:
namespace foo
{
void bar()
{
doSomething();
…
}
}
Run Code Online (Sandbox Code Playgroud)
那是因为我以这种方式学习它并且它被用于我正在进行的项目中.直到最近,当我偶然发现一个使用using指令的项目时,我从未真正想过它:
using namespace foo;
void bar()
{
doSomething();
…
}
Run Code Online (Sandbox Code Playgroud)
最后,可以选择使用全名.我发现它非常繁琐,特别是当涉及到很多成员的课程时.在我看来,当文件的所有内容都是一个命名空间的一部分时,它没有多大意义.
void foo::bar()
{
doSomething();
…
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是哪一个应该是首选,为什么?特别是关于前两个选项(使用指令与重新打开命名空间).
我正在学习如何使用SFINAE.我正在尝试使用它来根据serialize()对象中函数的存在来选择函数实现.
这是我用来确定的代码,如果类型定义了serialize()函数:
template <typename T>
class HasSerialize {
private:
typedef char yes[1];
typedef char no[2];
template <typename C> static yes& test(char[sizeof(&C::serialize)]) ;
template <typename C> static no& test(...);
public:
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
Run Code Online (Sandbox Code Playgroud)
但是,它似乎在GCC和Clang上给出了完全相同的结果.假设以下代码:
template<bool T>
class NVPtypeSerializer {
public:
template<typename C>
static xmlChar* serialize(C value) {
// serize() is not available
}
};
template<>
struct NVPtypeSerializer<true> {
public:
template<typename T>
static xmlChar* serialize(T value) {
return value.serialize();
}
};
Run Code Online (Sandbox Code Playgroud)
这被称为:
foo = …Run Code Online (Sandbox Code Playgroud) 我很难弄清楚如何在 C# 中使父类函数可见。
假设我有一个模板类,它定义了一个函数 foo()
template <int Dim, typename Type>
public ref class FixedNP
{
public:
float foo() {return 1;};
};
Run Code Online (Sandbox Code Playgroud)
然后我有一个继承自 FixedNP 模板的类:
public ref class Vector3fP : public FixedNP<3, float>
{
}
Run Code Online (Sandbox Code Playgroud)
当我尝试从 C# 调用 foo() 函数时,例如。
Vector3fP bar = new Vector3fP();
bar.foo();
Run Code Online (Sandbox Code Playgroud)
它说函数 Vector3fP 不包含 foo 的定义。
当我将 foo() 的定义移动到 Vector3fP 类时,它工作正常。然而,这在实际代码中是不可行的,因为 FixedNP 模板包含相当多的函数,这些函数应该从大约 4 个不同的类中继承。
在互联网上搜索后,我发现添加
using FixedNP<3, float>::foo;
Run Code Online (Sandbox Code Playgroud)
到 Vector3fP 为某人修复了类似的问题。但是在我的情况下,它只会导致另一个错误,这次是在编译 C++/CLI 代码时:
错误 C3182:“Vector3fP”:成员使用声明或访问声明在托管类型中是非法的
任何建议如何使我的函数在 C# 中可见?
编辑
我终于发现问题是由于null值毕竟不是null引起的,因为其中一个构造函数没有将值初始化为零.有了这些知识,我想将我的问题改为以下内容:
如果参数应该为null,那么通过JNI将NULL/0/nullptr传递给Java方法是否安全?
到目前为止我发现的源代码结果不一致 - 有些人说使用JNI时,C中的NULL和Java中的null是相同的.有些像在remudada的答案中所链接的那样,表明它可能不完全正确.
老问题
使用JNI时是否可以使用null参数调用Java方法?
我尝试传递null(0,NULL或nullptr),但这会导致Segmentation故障.我也试过NewGlobalRefnull参数,但只返回null.
假设以下Java代码:
class Main {
public void javaFoo(Object o) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
从C++调用此方法将类似于:
env->CallVoidMethod(object, javaFooID, value);
Run Code Online (Sandbox Code Playgroud)
现在,如果我想value成为null,我该怎么办?
问题是我不能轻易避免传递null对象.有各种setter有多个参数,可能是null也可能不是null,其中null作为无效值:
public void setFoo(Object a, Object b, Object c, Object d) {
... // any parameter can be null
}
Run Code Online (Sandbox Code Playgroud)