可能重复:
模板中的类使用不完整
我有一个困扰我几个小时的问题.
最初我认为类型必须在实例化时完成,但我尝试的所有编译器都接受该类型在那时仍然是不完整的,只要它在翻译单元中的任何地方定义.
为了说明它,问题是关于这个简单程序的正确性:
template <typename T>
int size() {
return sizeof(T); // T is required to be complete in this expression
}
class test; // test is declared, but incomplete
int main() {
size<test>();
}
// [1] point of instantiation of size<test>()
class test {}; // Definition of test, now it is complete
Run Code Online (Sandbox Code Playgroud)
根据§14.6.4.1/ 1,实例化的点size<test>
是标记为[1]的行,此时类型test
仍然不完整.如果我们试图在sizeof(test)
那里执行操作,编译器将无法告诉我们类型是不完整的.然而,调用一个模板,其中执行相同精确操作的类型在g ++,clang ++,comeau和Visual Studio 2010中编译.
以前的代码是否真的正确?如果在同一个翻译单元的任何地方完成,那么在标准中它支持用作模板参数的类型是否完整?或者什么时候必须完成?
我大概知道这个不能回答,但是我正在寻找是否有某种是否直接使用私有成员的指导或类方法中的公共访问器.
例如,考虑以下代码(在Java中,但在C++中看起来非常相似):
public class Matrix {
// Private Members
private int[][] e;
private int numRows;
private int numCols;
// Accessors
public int rows(){ return this.numRows; }
public int cols(){ return this.numCols; }
// Class Methods
// ...
public void printDimensions()
{
// [A] Using private members
System.out.format("Matrix[%d*%d]\n", this.numRows, this.numCols);
// [B] Using accessors
System.out.format("Matrix[%d*%d]\n", this.rows(), this.cols());
}
Run Code Online (Sandbox Code Playgroud)
该printDimensions()
函数说明了两种获取相同信息的方法,[A]使用私有成员(this.numRows, this.numCols
)或[B]通过访问者(this.rows(), this.cols()
).
一方面,您可能更喜欢使用访问器,因为您无法无意中更改私有成员变量的值.另一方面,您可能更喜欢直接访问私有成员,希望它可以删除不必要的函数调用.
我想我的问题是,要么是事实上的标准还是首选标准?
有着众所周知的C++联合攻击战斗机(JSF)标准,是否有类似的C标准,在编写任务关键平台时能够促进C程序员的使用质量?
我正在尝试为返回流的二叉树实现一个方法.我想使用方法中返回的流来显示屏幕中的树或将树保存在文件中:
这两个方法都在二叉树的类中:
声明:
void streamIND(ostream&,const BinaryTree<T>*);
friend ostream& operator<<(ostream&,const BinaryTree<T>&);
template <class T>
ostream& operator<<(ostream& os,const BinaryTree<T>& tree) {
streamIND(os,tree.root);
return os;
}
template <class T>
void streamIND(ostream& os,Node<T> *nb) {
if (!nb) return;
if (nb->getLeft()) streamIND(nb->getLeft());
os << nb->getValue() << " ";
if (nb->getRight()) streamIND(nb->getRight());
}
Run Code Online (Sandbox Code Playgroud)
这个方法在UsingTree类中:
void UsingTree::saveToFile(char* file = "table") {
ofstream f;
f.open(file,ios::out);
f << tree;
f.close();
}
Run Code Online (Sandbox Code Playgroud)
所以我重载了BinaryTree类的运算符"<<"以使用:cout << tree和ofstream f << tree,但是我收到了下一条错误消息:对`operator <<的未定义引用(std :: basic_ostream>&,二叉树&)"
PS树存储Word对象(带有int的字符串).
我希望你能理解我的英语不好.谢谢!而且我想知道一个关于STL的初学者的好文本,它解释了所有必要的,因为我浪费了所有时间在这样的错误.
编辑:saveToFile()中的树被声明:BinaryTree <Word>树.
我刚刚开始使用Visual Studio(我从dreamspark获得了VS 2012,并且我已经开始使用Windows了很长时间)并且我遇到了一些麻烦.
我的Source Files文件夹下有一个名为"main.c"的文件,如下所示:
#include <stdio.h>
typedef struct S_s S;
struct S_s {
void* x;
};
int main(int argc, char** argv)
{
int N;
scanf("%d", &N);
S* s;
printf("%p", s);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试构建它时,给出了以下错误消息:
Error 3 error C2065: 's' : undeclared identifier c:\users\math4tots\documents\visual studio 2012\projects\algorithms\lecture1\main.c 13 1 Lecture1
Error 4 error C2065: 's' : undeclared identifier c:\users\math4tots\documents\visual studio 2012\projects\algorithms\lecture1\main.c 14 1 Lecture1
Error 2 error C2275: 'S' : illegal use of this type as an expression c:\users\math4tots\documents\visual studio 2012\projects\algorithms\lecture1\main.c …
Run Code Online (Sandbox Code Playgroud) 由于大多数人都喜欢谜题,我会用一个(拼写错误:)开始这个问题.想得到介绍,请注意,如果你不关心它,你可以跳过热身(JG问题)并阅读G问题,因为那是我的"真正的问题".
在审查潜在新员工提供的代码示例时,您偶然发现了一个链接列表,其实现使用了现代C++ 11特性,即std :: unique_ptr <>.
template <typename T>
struct Node {
T data;
std::unique_ptr<Node<T>> next;
Node () {}
Node(const T& data_): data(data_) {}
Node(Node& other) { std::static_assert(false,"OH NOES"); }
Node& operator= (const Node& other) {
std::static_assert(false,"OH NOES");
return *new Node();
}
public:
void addNext(const T& t) {
next.reset(new Node<T>(t));
}
};
template<typename T>
class FwdList
{
std::unique_ptr<Node<T>> head;
public:
void add(const T& t)
{
if (head == nullptr)
head.reset( new Node<T>(t));
else {
Node<T>* curr_node = head.get(); …
Run Code Online (Sandbox Code Playgroud) 我有一个功能
template <typename T1, typename T2>
/*return type*/ foo(MyClass<T1>& bar1, MyClass<T2>& bar2)
{
if (something)
return bar1;
else
return bar2;
}
Run Code Online (Sandbox Code Playgroud)
问题是,我不知道这个函数会返回什么:它可以是MyClass<T1>
或者MyClass<T2>
.
我怎样才能让它发挥作用?
T1和T2是3个整数的结构,在编译时已知.返回类型取决于那些中较小的2:例如,对于T1 = <5, 1, 1>
T2 = <4, 4, 7>
返回类型应该是MyClass<T2>
.
用法示例:
MyClass<5, 2, 8> m1;
MyClass<4, 2, 1> m2;
cout << foo(m1, m2); //should print m2 (I have a method used for that)
Run Code Online (Sandbox Code Playgroud) 在命名空间级别直接使用c ++中的枚举是不好的做法?我的意思是没有与任何课程相关联?假设我有一个enum和一个看起来像这样的类,
enum Player { USER, COMPUTER}
class Game {
//Logic of the game.
};
Run Code Online (Sandbox Code Playgroud)
那么我应该宣布玩家枚举为游戏类的成员吗?它应该是私人的吗?
我已经为我的程序添加了一个类并进行了测试.我真的很惊讶有任何真正的错误.这是代码:
#pragma once
#include "Iingredient.h"
#include <string>
#include <vector>
using namespace std;
ref class Recipe{
private:
string partsName;
vector<Iingredient> ing;
public:
Recipe(){}
};
Run Code Online (Sandbox Code Playgroud)
以下是错误:
错误23错误C4368:无法将'partsName'定义为托管'Recipe'的成员:不支持混合类型c:\ users\user\documents\visual studio 2010\projects\smestras2_l1\Recipe.h 10 1 file2_L1
错误24错误C4368:无法将'ing'定义为托管'Recipe'的成员:不支持混合类型c:\ users\user\documents\visual studio 2010\projects\smestras2_l1\Recipe.h 11 1 file2_L1
我google了一下,发现它有关托管和非托管代码.如何解决这个问题?它是否与manged和非托管代码相关?如果是这样的话?
char* stringReturn()
{
char a[] = "Array of characters";
//return a; // I know stack allocation should not be returned
char *b = "Pointer to a string";
return b; // Is it safe ?
}
int main() {
char *str = stringReturn ();
cout<< str;
return 0; }
Run Code Online (Sandbox Code Playgroud)
这是安全的,然后将数据"指向字符串的指针"存储在存储器中.