指示汇编时间叫什么构造函数
Indicate compile time what constructor was called
我有以下类
template<typename T>
class A
{
public:
A(T* d) : ptr(d)
{}
A(const T* d) : ptr(const_cast<T*>(d))
{}
T* Ptr()
{
static_assert(???, "Not allowed when using A(const T* d)");
return ptr;
}
const T* Ptr() const
{
return ptr;
}
private:
T* ptr;
}
在编译ptr()时,我知道如何实现这一目标,我知道使用哪个构造函数来创建此对象?我想静态地断言,当汇编ptr()时,使用了consstructor a(t* d):
unsigned char* ptr = new unsigned char[10];
const unsigned char* cptr = new unsigned char[10];
A a(ptr);
A ca(cptr);
a.Ptr(); // Compiles
ca.Ptr(); // Gives compile error
我想检测到编译时间,如果程序员使用const ptr创建A类的对象时,请调用PTR()。不允许使用const ptr创建时调用foo
我想像这个
一样使用它void Foo(A<int>& r)
{
....
int* ptr = a.Ptr();
....
}
void Bar(const A<int>& r)
{
...
}
...
A a(ptr);
A ca(cptr);
Bar(a);
Bar(ac);
Foo(a);
Foo(ac);// Gives compile error
最简单的C 17(我可以告诉您无论如何都使用它来推断模板参数类型)方法是使用用户定义的扣除指南和其他标记非类型的非类型模板参数:
enum Tag { //
NonConstTag, // Additional tag enum
ConstTag //
}; //
template<typename T, Tag TT>
// ^^^^^^
// Additional non-type template parameter to provide
// different type of A in case of calling const parameter
// constructor
class A
{
public:
A(T* d) : ptr(d)
{}
A(const T* d) : ptr(const_cast<T*>(d))
{}
T* Ptr()
{
static_assert(TT == NonConstTag, "Not allowed when using A(const T* d)");
return ptr;
}
const T* Ptr() const
{
return ptr;
}
private:
T* ptr;
};
template<typename T> //
A(T* d) -> A<T, NonConstTag>; //
// Deduction guides
template<typename T> //
A(const T* d) -> A<T, ConstTag>; //
int main() {
unsigned char* ptr = new unsigned char[10];
const unsigned char* cptr = new unsigned char[10];
A a(ptr);
A ca(cptr);
a.Ptr(); // Compiles
//ca.Ptr(); // Gives compile error
}
[live demo]
编辑:
有点改进以满足const正确性:
enum Tag {
NonConstTag,
ConstTag
};
template<typename T, Tag TT>
class A
{
public:
A(T* d) : ptr(d), cptr(d)
{}
A(const T* d) : ptr(nullptr), cptr(d)
{}
T* Ptr()
{
static_assert(TT == NonConstTag, "Not allowed when using A(const T* d)");
return ptr;
}
const T* Ptr() const
{
return cptr;
}
private:
T* ptr;
const T* cptr;
};
template<typename T>
A(T* d) -> A<T, NonConstTag>;
template<typename T>
A(const T* d) -> A<T, ConstTag>;
int main() {
unsigned char* ptr = new unsigned char[10];
const unsigned char* cptr = new unsigned char[10];
A a(ptr);
A ca(cptr);
a.Ptr(); // Compiles
//ca.Ptr(); // Gives compile error
}
[live demo]
如果您有IDE,则可以使您跳到与呼叫相对应的声明。(YouCompleteme在VIM中使用:YcmCompleter GoTo
来做到这一点;如果我没记错的话,Visual Studio具有F12或Alt-F12)。
除此之外,如果要检测到运行时,请设置标志:
template <typename T> class A {
public:
A(T *) {}
A(const T *) : used_const_arg_ctor(true) {}
private:
bool used_const_arg_ctor = false;
void Foo() {
if (used_const_arg_ctor) {
}
}
};
实际静态断言,使其成为constexpr类型:
#include <boost/asio.hpp>
template <typename T> class A {
public:
constexpr A(T *) {}
constexpr A(const T *) : used_const_arg_ctor(true) {}
constexpr bool Foo() const {
return used_const_arg_ctor;
}
private:
bool used_const_arg_ctor = false;
};
int main() {
int const i = 42;
constexpr A<int> a(&i);
static_assert(a.Foo(), "is constructed from const pointer");
}
这有限。我建议让T
反映constness:
template <typename T> class A {
public:
A(T*d) : _v(d) {}
constexpr bool IsConst() const { return std::is_const<T>::value; }
private:
T* _v;
};
相关文章:
- 是什么让放置新调用对象的构造函数?
- 如果我真的真的想从 STL 容器继承,并且我继承构造函数并删除新运算符,会发生什么?
- 使用基类指针调用基类的值构造函数的语法是什么?
- 这个C++编译器优化(在自身的实例上调用对象自己的构造函数)的名称是什么,它是如何工作的?
- 构造函数后面的宏.什么意思?
- C++构造函数内部会发生什么?
- 用相同的参数声明两个构造函数的最偶像化的方法是什么?
- 如果在 C++ 构造函数中以错误的顺序初始化对象数据,会发生什么类型的错误
- 我是否为邪恶刽子手的构造函数错过了什么?
- 构造函数中没有参数的对象类成员按什么顺序初始化?
- 什么时候用指针调用C++类构造函数
- 这个构造函数是做什么的
- 将复制构造函数设置为private和=delete有什么区别
- 我不明白在这个例子中什么时候调用构造函数
- 在C++中,从构造函数中将字符串文本分配给成员const char*变量时会发生什么
- c++ 17 中结构自动定义构造函数的规则是什么?
- 在C++中初始化带有和不使用构造函数调用的对象有什么区别
- 指示汇编时间叫什么构造函数
- 在这种情况下调用什么构造函数
- 使用什么构造函数