求教一个关于constexpr的问题

Zxy0918520 2016-10-06 01:05:00
#include <iostream>

class _A
{
public:
_A();
~_A();

constexpr int b() { return c; } //①:这个可不可以类里声明,类外定义。

int a(int _z);

private:

int c;

int d;

};

int _A::a(int _z)

{
c = _z;

return 0;

}


_A::_A()
{

c = 0;

d = 0;

}

_A::~_A()
{
}

int main()

{
_A q;

int w{ 0 };

std::cin >> w;

q.a(w);

std::cout << q.b();


return 0;
}


①的部分可不可以写成这样啊
class _A
{
public:
_A();
~_A();

constexpr int b();
int a(int _z);

private:

int c;

int d;

};

constexpr int _A::b()

{

return c;
}
...全文
189 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
Zxy0918520 2016-10-06
  • 打赏
  • 举报
回复
引用 8 楼 fefe82 的回复:
先纠正一个错误。constepxr函数是inline的,所以定义不能和声明分离。函数可以不写在类的定义里面(如 #2 楼),但是必须和声明在同一个文件里。(比如,在 A.h 里声明,在 A.cpp 里定义,在 main.cpp 里调用是不行的。但是声明定义都放在 A.h 里是可以的) ====================================================================== b() 可以作为一个 constexpr 函数用,不过:
#include <iostream>
class _A
{
public:
    // _A 需要是一个 literal type ,以便 (某些) _A 的对象可以调用 constexpr 函数 b();
    constexpr _A():c{1}{};  // literal type 需要 constexpr 构造
    //~_A(); // literal type 需要 trivial destructor
    int a();
    constexpr int b() const{return c;}; // 注意,这里 c 依然不是一个常量表达式
private:
    int c;
};

int _A::a()
{
    int d;
    //while (std::cin >> d)
    //{
        std::cout << d << "   ";
        c++;
    //}
    std::cout << std::endl;
    return 0;
}

int main()
{
    _A r;
    r.a();
    std::cout<<r.b();

    // 需要通过一个 constexpr 对象来调用 b();
    // 非 literal type 不能声明 constexpr 对象
    constexpr _A k;
    // OK!!! x.b() 是一个常量表达式
    int x[k.b()];
    return 0;
}
[quote=引用 7 楼 Zxy0918520 的回复:] [quote=引用 6 楼 fefe82 的回复:] [quote=引用 5 楼 Zxy0918520 的回复:] [quote=引用 4 楼 fefe82 的回复:] [quote=引用 3 楼 Zxy0918520 的回复:] [quote=引用 1 楼 fefe82 的回复:] 当然可以。 只是在看不到它的定义的地方,它不能用于一个常量表达式。
知道了 谢谢,,那像#2版主那样还是一个常量表达式 么,什么叫做看不到他定义的地方。。[/quote] 调用和定义不在一个(把 #include 都展开之后的)源文件里,那么调用的地方就是看不到定义。在同一个源文件(这个实际应该叫“编译单元”)里就是可见的。 C++ 常量表达式 的条件蛮复杂的,你不把程序写全不太好判断。 不过,如果调用与定义不在同一个编译单元的话,那么包含调用的表达式必然不是常量表达式。 ================================================ constexpr int b() const; // 这个一个函数声明,不是表达式 constexpr int _A::b() const { return 2; } // 这个一个函数定义,也不是表达式 以上两个,都不是表达式,当然也就不是常量表达式。[/quote]不好意思刚刚是我表述不当
#include <iostream>

class _A
{
public:
	_A();
	~_A();

	int a();

	constexpr int b() const;

private:

	int c;

};

int _A::a()

{
	int d;

	while (std::cin >> d)
	{
		std::cout << d << "   ";

		c++;
	}

	std::cout << std::endl;

	return 0;

}

constexpr int _A::b() const

{
	return c;                                       //我想问的是这里的返回值c是否作为一个常量表达式。
}

_A::_A() :c{0}
{
}

_A::~_A()
{
}

int main()

{

	_A r;

	r.a();

	std::cout<<r.b();

	return 0;
}
[/quote] 不是。[/quote] 这个函数b()的返回值是non-constant c是不是导致即使被修饰成constexpr函数,函数b()也不能作为一个常量表达式来使用啊,这个
constexpr int _A::b() const

{
	return c;                                   
}
岂不是没什么意义么。。[/quote][/quote]非常非常感谢 最后一个问题。。
#include <iostream>

#define _m 1000

class _A
{
public:
	constexpr _A() :c{ 1 } {};
								
	int a();
	constexpr int b() const { return c; }; 
private:
	int c;

	int *p;  ///这里加个指向int的指针并用new申请空间大小为c,c初始化为_m大小,就是c{_m};p=new int[c];constexpr构造函数好像不好写啊
			///constexpr构造函数要求函数主体为空.还有 这个析构函数怎么写。。。。
};

int _A::a()
{
	int d;

	std::cin >> d;
	//while (std::cin >> d)
	//{
	std::cout << d << "   ";
	c++;
	//}
	std::cout << std::endl;
	return 0;
}

int main()
{
	_A r;
	r.a();
	std::cout << r.b();

	// 需要通过一个 constexpr 对象来调用 b();
	// 非 literal type 不能声明 constexpr 对象
	constexpr _A k;
	// OK!!! x.b() 是一个常量表达式
	int x[k.b()];
	return 0;
}
fefe82 2016-10-06
  • 打赏
  • 举报
回复
先纠正一个错误。constepxr函数是inline的,所以定义不能和声明分离。函数可以不写在类的定义里面(如 #2 楼),但是必须和声明在同一个文件里。(比如,在 A.h 里声明,在 A.cpp 里定义,在 main.cpp 里调用是不行的。但是声明定义都放在 A.h 里是可以的) ====================================================================== b() 可以作为一个 constexpr 函数用,不过:
#include <iostream>
class _A
{
public:
    // _A 需要是一个 literal type ,以便 (某些) _A 的对象可以调用 constexpr 函数 b();
    constexpr _A():c{1}{};  // literal type 需要 constexpr 构造
    //~_A(); // literal type 需要 trivial destructor
    int a();
    constexpr int b() const{return c;}; // 注意,这里 c 依然不是一个常量表达式
private:
    int c;
};

int _A::a()
{
    int d;
    //while (std::cin >> d)
    //{
        std::cout << d << "   ";
        c++;
    //}
    std::cout << std::endl;
    return 0;
}

int main()
{
    _A r;
    r.a();
    std::cout<<r.b();

    // 需要通过一个 constexpr 对象来调用 b();
    // 非 literal type 不能声明 constexpr 对象
    constexpr _A k;
    // OK!!! x.b() 是一个常量表达式
    int x[k.b()];
    return 0;
}
引用 7 楼 Zxy0918520 的回复:
[quote=引用 6 楼 fefe82 的回复:] [quote=引用 5 楼 Zxy0918520 的回复:] [quote=引用 4 楼 fefe82 的回复:] [quote=引用 3 楼 Zxy0918520 的回复:] [quote=引用 1 楼 fefe82 的回复:] 当然可以。 只是在看不到它的定义的地方,它不能用于一个常量表达式。
知道了 谢谢,,那像#2版主那样还是一个常量表达式 么,什么叫做看不到他定义的地方。。[/quote] 调用和定义不在一个(把 #include 都展开之后的)源文件里,那么调用的地方就是看不到定义。在同一个源文件(这个实际应该叫“编译单元”)里就是可见的。 C++ 常量表达式 的条件蛮复杂的,你不把程序写全不太好判断。 不过,如果调用与定义不在同一个编译单元的话,那么包含调用的表达式必然不是常量表达式。 ================================================ constexpr int b() const; // 这个一个函数声明,不是表达式 constexpr int _A::b() const { return 2; } // 这个一个函数定义,也不是表达式 以上两个,都不是表达式,当然也就不是常量表达式。[/quote]不好意思刚刚是我表述不当
#include <iostream>

class _A
{
public:
	_A();
	~_A();

	int a();

	constexpr int b() const;

private:

	int c;

};

int _A::a()

{
	int d;

	while (std::cin >> d)
	{
		std::cout << d << "   ";

		c++;
	}

	std::cout << std::endl;

	return 0;

}

constexpr int _A::b() const

{
	return c;                                       //我想问的是这里的返回值c是否作为一个常量表达式。
}

_A::_A() :c{0}
{
}

_A::~_A()
{
}

int main()

{

	_A r;

	r.a();

	std::cout<<r.b();

	return 0;
}
[/quote] 不是。[/quote] 这个函数b()的返回值是non-constant c是不是导致即使被修饰成constexpr函数,函数b()也不能作为一个常量表达式来使用啊,这个
constexpr int _A::b() const

{
	return c;                                   
}
岂不是没什么意义么。。[/quote]
Zxy0918520 2016-10-06
  • 打赏
  • 举报
回复
引用 6 楼 fefe82 的回复:
[quote=引用 5 楼 Zxy0918520 的回复:] [quote=引用 4 楼 fefe82 的回复:] [quote=引用 3 楼 Zxy0918520 的回复:] [quote=引用 1 楼 fefe82 的回复:] 当然可以。 只是在看不到它的定义的地方,它不能用于一个常量表达式。
知道了 谢谢,,那像#2版主那样还是一个常量表达式 么,什么叫做看不到他定义的地方。。[/quote] 调用和定义不在一个(把 #include 都展开之后的)源文件里,那么调用的地方就是看不到定义。在同一个源文件(这个实际应该叫“编译单元”)里就是可见的。 C++ 常量表达式 的条件蛮复杂的,你不把程序写全不太好判断。 不过,如果调用与定义不在同一个编译单元的话,那么包含调用的表达式必然不是常量表达式。 ================================================ constexpr int b() const; // 这个一个函数声明,不是表达式 constexpr int _A::b() const { return 2; } // 这个一个函数定义,也不是表达式 以上两个,都不是表达式,当然也就不是常量表达式。[/quote]不好意思刚刚是我表述不当
#include <iostream>

class _A
{
public:
	_A();
	~_A();

	int a();

	constexpr int b() const;

private:

	int c;

};

int _A::a()

{
	int d;

	while (std::cin >> d)
	{
		std::cout << d << "   ";

		c++;
	}

	std::cout << std::endl;

	return 0;

}

constexpr int _A::b() const

{
	return c;                                       //我想问的是这里的返回值c是否作为一个常量表达式。
}

_A::_A() :c{0}
{
}

_A::~_A()
{
}

int main()

{

	_A r;

	r.a();

	std::cout<<r.b();

	return 0;
}
[/quote] 不是。[/quote] 这个函数b()的返回值是non-constant c是不是导致即使被修饰成constexpr函数,函数b()也不能作为一个常量表达式来使用啊,这个
constexpr int _A::b() const

{
	return c;                                   
}
岂不是没什么意义么。。
fefe82 2016-10-06
  • 打赏
  • 举报
回复
引用 5 楼 Zxy0918520 的回复:
[quote=引用 4 楼 fefe82 的回复:] [quote=引用 3 楼 Zxy0918520 的回复:] [quote=引用 1 楼 fefe82 的回复:] 当然可以。 只是在看不到它的定义的地方,它不能用于一个常量表达式。
知道了 谢谢,,那像#2版主那样还是一个常量表达式 么,什么叫做看不到他定义的地方。。[/quote] 调用和定义不在一个(把 #include 都展开之后的)源文件里,那么调用的地方就是看不到定义。在同一个源文件(这个实际应该叫“编译单元”)里就是可见的。 C++ 常量表达式 的条件蛮复杂的,你不把程序写全不太好判断。 不过,如果调用与定义不在同一个编译单元的话,那么包含调用的表达式必然不是常量表达式。 ================================================ constexpr int b() const; // 这个一个函数声明,不是表达式 constexpr int _A::b() const { return 2; } // 这个一个函数定义,也不是表达式 以上两个,都不是表达式,当然也就不是常量表达式。[/quote]不好意思刚刚是我表述不当
#include <iostream>

class _A
{
public:
	_A();
	~_A();

	int a();

	constexpr int b() const;

private:

	int c;

};

int _A::a()

{
	int d;

	while (std::cin >> d)
	{
		std::cout << d << "   ";

		c++;
	}

	std::cout << std::endl;

	return 0;

}

constexpr int _A::b() const

{
	return c;                                       //我想问的是这里的返回值c是否作为一个常量表达式。
}

_A::_A() :c{0}
{
}

_A::~_A()
{
}

int main()

{

	_A r;

	r.a();

	std::cout<<r.b();

	return 0;
}
[/quote] 不是。
Zxy0918520 2016-10-06
  • 打赏
  • 举报
回复
引用 4 楼 fefe82 的回复:
[quote=引用 3 楼 Zxy0918520 的回复:] [quote=引用 1 楼 fefe82 的回复:] 当然可以。 只是在看不到它的定义的地方,它不能用于一个常量表达式。
知道了 谢谢,,那像#2版主那样还是一个常量表达式 么,什么叫做看不到他定义的地方。。[/quote] 调用和定义不在一个(把 #include 都展开之后的)源文件里,那么调用的地方就是看不到定义。在同一个源文件(这个实际应该叫“编译单元”)里就是可见的。 C++ 常量表达式 的条件蛮复杂的,你不把程序写全不太好判断。 不过,如果调用与定义不在同一个编译单元的话,那么包含调用的表达式必然不是常量表达式。 ================================================ constexpr int b() const; // 这个一个函数声明,不是表达式 constexpr int _A::b() const { return 2; } // 这个一个函数定义,也不是表达式 以上两个,都不是表达式,当然也就不是常量表达式。[/quote]不好意思刚刚是我表述不当
#include <iostream>

class _A
{
public:
	_A();
	~_A();

	int a();

	constexpr int b() const;

private:

	int c;

};

int _A::a()

{
	int d;

	while (std::cin >> d)
	{
		std::cout << d << "   ";

		c++;
	}

	std::cout << std::endl;

	return 0;

}

constexpr int _A::b() const

{
	return c;                                       //我想问的是这里的返回值c是否作为一个常量表达式。
}

_A::_A() :c{0}
{
}

_A::~_A()
{
}

int main()

{

	_A r;

	r.a();

	std::cout<<r.b();

	return 0;
}
fefe82 2016-10-06
  • 打赏
  • 举报
回复
引用 3 楼 Zxy0918520 的回复:
[quote=引用 1 楼 fefe82 的回复:] 当然可以。 只是在看不到它的定义的地方,它不能用于一个常量表达式。
知道了 谢谢,,那像#2版主那样还是一个常量表达式 么,什么叫做看不到他定义的地方。。[/quote] 调用和定义不在一个(把 #include 都展开之后的)源文件里,那么调用的地方就是看不到定义。在同一个源文件(这个实际应该叫“编译单元”)里就是可见的。 C++ 常量表达式 的条件蛮复杂的,你不把程序写全不太好判断。 不过,如果调用与定义不在同一个编译单元的话,那么包含调用的表达式必然不是常量表达式。 ================================================ constexpr int b() const; // 这个一个函数声明,不是表达式 constexpr int _A::b() const { return 2; } // 这个一个函数定义,也不是表达式 以上两个,都不是表达式,当然也就不是常量表达式。
Zxy0918520 2016-10-06
  • 打赏
  • 举报
回复
引用 1 楼 fefe82 的回复:
当然可以。 只是在看不到它的定义的地方,它不能用于一个常量表达式。
知道了 谢谢,,那像#2版主那样还是一个常量表达式 么,什么叫做看不到他定义的地方。。
paschen 版主 2016-10-06
  • 打赏
  • 举报
回复
可以:

class _A
{
public:
	constexpr int b() const;
};

constexpr int _A::b() const
{
	return 2;
}
fefe82 2016-10-06
  • 打赏
  • 举报
回复
当然可以。 只是在看不到它的定义的地方,它不能用于一个常量表达式。

64,282

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧