我目前正在使用Java进行基于文本的冒险,以便将其用作测试平台,尝试从我正在阅读的这本Java书中学到的新东西.
我现在正在尝试声明一个子类的实例(因为播放器的脚本是为了找到它).父类是Item,它有两个子类:Weapon和Armour.
但是,无论我尝试和声明它的方式,我正在使用的IDE(Eclipse)标记该行,并出现以下错误:
不能访问类型为Item的封闭实例.必须使用Item类型的封闭实例限定分配(例如,xx是A(),其中x是Item的实例).
当我尝试将其声明为以下任何一项时:
Item machinePistol = new Weapon();
Weapon machinePistol = new Weapon();
Item machinePistol = new Item.Weapon();
Weapon machinePistol = new Item.Weapon();
Run Code Online (Sandbox Code Playgroud)
作为参考,item类看起来像这样:
package JavaAIO;
public class Item
{
public String itemName;
public double itemWeight;
public class Weapon extends Item
{
public double damage;
public double speed;
}
public class Armour extends Item
{
public double dmgResist;
public double attSpdMod;
}
}
Run Code Online (Sandbox Code Playgroud)
所以如果有人能告诉我如何正确地实例化武器(所以我可以设置其字段的值并将其交给玩家),我将非常感激.
我有一个非常复杂的课程:
class C:
pass
Run Code Online (Sandbox Code Playgroud)
我有这个测试代码:
for j in range(10):
c = C()
print c
Run Code Online (Sandbox Code Playgroud)
这使 :
<__main__.C instance at 0x7f7336a6cb00>
<__main__.C instance at 0x7f7336a6cab8>
<__main__.C instance at 0x7f7336a6cb00>
<__main__.C instance at 0x7f7336a6cab8>
<__main__.C instance at 0x7f7336a6cb00>
<__main__.C instance at 0x7f7336a6cab8>
<__main__.C instance at 0x7f7336a6cb00>
<__main__.C instance at 0x7f7336a6cab8>
<__main__.C instance at 0x7f7336a6cb00>
<__main__.C instance at 0x7f7336a6cab8>
Run Code Online (Sandbox Code Playgroud)
人们可以很容易地看到Python切换到两个不同的值.在某些情况下,这可能是灾难性的(例如,如果我们将对象存储在其他复杂对象中).
现在,如果我将对象存储在List中:
lst = []
for j in range(10):
c = C()
lst.append(c)
print c
Run Code Online (Sandbox Code Playgroud)
我明白了:
<__main__.C instance at 0x7fd8f8f7eb00>
<__main__.C instance at 0x7fd8f8f7eab8> …Run Code Online (Sandbox Code Playgroud) python for-loop memory-management reference-counting instantiation
我有一个包含矢量的模板类.我试图在这个类中存储unique_ptrs,它工作正常.但是,当我将void add(const T& elem)函数标记为虚拟时,我的编译器(clang)告诉我,我正在为unique_ptr进行"调用隐式删除的复制构造函数".
我知道unique_ptrs无法复制,所以这就是我创建void add(T&& elem)函数的原因.我只是不知道为什么将其他添加函数标记为虚拟导致编译器错误.
谢谢你的时间.
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
template <typename T>
class ContainerWrapper {
private:
vector<T> vec;
public:
ContainerWrapper() : vec() {
}
//Marking this as virtual causes a compiler error
void add(const T& elem) {
vec.push_back(elem);
}
void add(T&& elem) {
vec.push_back(std::move(elem));
}
T removeLast() {
T last = std::move(vec.back());
vec.pop_back();
return last;
}
};
int main() {
ContainerWrapper<unique_ptr<string>> w;
w.add(unique_ptr<string>(new string("hello")));
unique_ptr<string> s = w.removeLast(); …Run Code Online (Sandbox Code Playgroud) 我正在努力访问类模板中定义的静态成员函数.在头文件TemplateTest.h中,我将主类模板定义为:
#include<iostream>
template<class T, class U>
struct TemplateTest
{
public:
void static invoke();
/*{
std::cout << "Should not be called" << std::endl;
}*/
};
Run Code Online (Sandbox Code Playgroud)
然后源文件TemplateTester.cpp我把一个专业化:
#include "TemplateTest.h"
template<>
struct TemplateTest<int, bool>
{
static void invoke()
{
std::cout << "invoke<int, bool>" << std::endl;
}
};
template struct TemplateTest<int, bool>; //instantiate to resolve linker issue
Run Code Online (Sandbox Code Playgroud)
我明确地实例化了类,因此链接器正确解析.
在驱动程序driver.cpp中:
include "TemplateTest.h"
int main()
{
TemplateTest<int, bool>::invoke();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我使用g ++编译TemplateTest.cpp时,它会正确生成目标文件,但是当我尝试将其链接到驱动程序类时,它会给我的链接器错误"未定义引用`TemplateTest :: invoke()"
我经历了像这样的其他相关帖子,但我没有尝试访问功能模板.
任何线索都非常感谢.
在查看了关于在C++中使用新的"随机"工具的各种示例之后,我对最佳实践感到有些困惑 - 特别是与各种实例的生命周期有关.
例如,在一些示例中,"random_device"的使用在诸如函数的局部范围中是静态的,或者是静态全局变量或者仅仅是本地的.
--- TU ---
static std::random_device global_source;
void foo()
{
static std::random_device local_static_source;
static std::mt19937 gen(local_static_source());
std::uniform_int_distribution<> dist(0,10);
...
dist(gen);
...
}
void boo()
{
std::mt19937 gen(global_source());
std::uniform_int_distribution<> dist(0,10);
...
dist(gen);
...
}
void roo()
{
std::random_device local_source;
std::mt19937 gen(local_source());
std::uniform_int_distribution<> dist(0,10);
...
dist(gen);
...
}
int main()
{
static std::mt19937 gen(global_source());
std::uniform_int_distribution<> dist(0,10);
...
dist(gen);
...
return 0;
}
--- TU ---
Run Code Online (Sandbox Code Playgroud)
Q1:如果多个线程可以访问"foo"或"boo",那么生成器和源是否可以是静态的? - 有没有像shared_ptr那样的线程安全保证?
问题2:标准中是否有任何措辞可以讨论与实例化相关的假设和问题?
该代码可以编译吗?
#include <iostream>
template <typename T>
struct TMPL
{
using TP = typename T::TP; //is CL::TP visible (with T == CL)?
};
struct CL
{
using TP = int;
TMPL<CL>::TP val;
};
int main()
{
CL cl;
}
Run Code Online (Sandbox Code Playgroud)
根据标准14.6.4.1/4,在CL类定义之前立即实例化TMPL
对于类模板专业化,...,如果专业化隐式实例化,因为它是从另一个模板特内引用,...... 否则,实例化的这样一个专业化的点后面紧跟的命名空间范围声明或定义,是指专业化.
因此,CL :: TP在TMPL实例化点中不可见,但所有编译器(MSVC,gcc,clang)都编译得很好.我还发现了一份缺陷报告http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#287,但显然未被接受
看起来Clang(3.8)和GNU C++(4.9)中模板实例化的规则是不一样的.这是一个例子:
#include <cstddef>
template <bool>
class Assert {
Assert(); // private constructor for Assert<false>
};
template <>
class Assert<true> { // implicit public constructor for Assert<true>
};
template <size_t N>
class A {
};
template <class T, size_t N>
T foo(A<N>) {
return T(N - 1);
}
template <class T>
T foo(A<0>) { // foo is not defined for N=0
Assert<false>();
return T(0);
}
int main(int argc, char **argv) {
foo<int>(A<3>());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这个最小的例子显示了一个模板函数,foo它是在一个类型T和一个自然数上推广的 …
我一直在试验可组合管道的系统,该系统涉及一组“阶段”,这些阶段可以进行模板化。每个阶段都处理自己的设置,执行和清除,模板推导用于构建管道使用的“状态”的最小列表。这需要很多样板模板代码,这些代码显示出一些明显不协调的行为。尽管进行了成功的实验,但实际上将其滚动到我们的代码库中仍会由于无效实例化而导致错误。
花了一些时间来找出玩具(工作)解决方案与功能更丰富的版本之间的区别,但最终将其缩小为一个明确的命名空间规范。
template<typename KeyType = bool>
struct bind_stage
{
static_assert(!std::is_same<KeyType, bool>::value, "Nope, someone default instantiated me");
};
template<typename BoundStage, typename DefaultStage>
struct test_binding {};
template<template<typename...>class StageTemplate, typename S, typename T>
struct test_binding <StageTemplate<S>, StageTemplate<T>> {};
template<typename T>
auto empty_function(T b) {}
Run Code Online (Sandbox Code Playgroud)
然后我们的主要:
int main()
{
auto binder = test_binding<bind_stage<int>, bind_stage<>>();
//empty_function(binder); // Fails to compile
::empty_function(binder); // Compiles happily
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在,我不确定是否会失败。一方面,我们创建了一个test_binder<bind_stage<int>,bind_stage<bool>>显然包含无效实例化bind_stage<bool>作为其类型定义一部分的a。哪个应该无法编译。
另一方面,它仅作为名称而不是定义包含在内。在这种情况下,它可能只是一个前向声明的模板,并且我们希望它可以工作,只要外部模板中没有任何东西专门引用它即可。
我没有想到的是两种不同的行为,具体取决于我是否添加了(理论上是多余的)全局名称空间说明符。
我已经在Visual Studio,Clang和GCC中尝试了此代码。所有人都有相同的行为,这使我摆脱了编译器错误。这种行为是由C ++标准中的某些原因解释的吗?
编辑:Daniel Langr的另一个例子对我来说意义不大:
template <typename T>
struct X { …Run Code Online (Sandbox Code Playgroud) c++ templates instantiation language-lawyer template-argument-deduction
静态变量在C#中具有与在C++中相同或相似的功能吗?
编辑:
使用C++,您可以在许多不同的上下文中使用静态变量 - 例如:1)全局变量,2)本地函数变量,3)类成员 - C#中的类似用法是否与C++类似?
我正在编写一个C++库,其中包含许多我希望显式实例化并导出多个类型参数的函数模板.在我的具体情况,我有很多的,我想单独实例化和编译数值函数模板float,double和long double.他们看起来像这样:
template <typename T>
T calculate_a(T x) { ... }
template <typename T>
T calculate_b(T x, T y) { ... }
// ...
Run Code Online (Sandbox Code Playgroud)
如果我有M个函数模板和N个底层类型,那么我有M*N显式实例化来输出.是否可以更简洁地编写这些实例?
我目前的解决方案是使用预处理器宏来执行给定类型的所有实例化:
#define EXPLICITLY_INSTANTIATE(T) \
template T calculate_a<T>(T x); \
template T calculate_b<T>(T x, T y); \
// ...
EXPLICITLY_INSTANTIATE(float);
EXPLICITLY_INSTANTIATE(double);
EXPLICITLY_INSTANTIATE(long double);
Run Code Online (Sandbox Code Playgroud)
但是,这不是最理想的,因为它要求我单独维护每个函数模板签名的另一个副本.另外,如果我想在多个翻译单元中执行此操作,那么我需要单独维护每个翻译单元中的基础类型列表.(假设C++ 2a添加了long long double我想要支持的类型;我必须添加EXPLICITLY_INSTANTIATE(long long double);到每个文件.)
另一种可能的方法是将我的所有函数收集到(仅限静态)模板类中:
template <typename T>
class calculate {
T a(T x) { ... }
T b(T x, T …Run Code Online (Sandbox Code Playgroud)