小编sta*_*tiv的帖子

最佳实践:使用命名空间还是重新打开命名空间?

假设我在头文件中声明了一个函数(或类,无所谓),它是命名空间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)

所以我的问题是哪一个应该是首选,为什么?特别是关于前两个选项(使用指令与重新打开命名空间).

c++ coding-style

14
推荐指数
2
解决办法
1676
查看次数

使用SFINAE在GCC和Clang上给出了不同的结果

我正在学习如何使用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++ gcc clang sfinae

6
推荐指数
1
解决办法
407
查看次数

C++/CLI:从模板类继承的函数在 C# 中不可见

我很难弄清楚如何在 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# 中可见?

.net c# c++-cli visual-studio-2010

5
推荐指数
1
解决办法
1514
查看次数

JNI将null参数传递给Java方法

编辑

我终于发现问题是由于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)

c++ java java-native-interface

5
推荐指数
1
解决办法
4081
查看次数