gpt4 book ai didi

c++ - Typedef、模板和 const 关键字

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:35:46 26 4
gpt4 key购买 nike

我在使用带有 const 关键字(用于函数参数类型)的模板时遇到问题,为了说明这一点,我创建了一个小代码:

template <typename ClassType, typename ReturnType, typename ... Args>
struct MethodCallerFactory
{
typedef ReturnType (*Type)(ClassType*, Args...);

template <ReturnType (ClassType::*Pointer)(Args...)>
struct Method
{
static Type createMethodCaller()
{
ReturnType (*caller)(ClassType*, Args...) = [](ClassType* obj, Args ... args) -> ReturnType
{
ReturnType (ClassType::*ptr)(Args...) = Pointer;
return (obj->*ptr)(args...);
};
return caller;
}
};
};


class Test
{
public :
void set(const int& p)
{
n = p;
}
void set2(int p)
{
n = p;
}
void set3(const int p)
{
n = p;
}
void set4(int& p)
{
n = p;
}
private :
int n;
};

typedef int& INTREF;
typedef int INTVALUE;

int main()
{
void (*ptr1)(Test*, const int&) = MethodCallerFactory<Test, void, const int&>::Method<&Test::set>::createMethodCaller();
void (*ptr2)(Test*, const INTREF) = MethodCallerFactory<Test, void, const INTREF>::Method<&Test::set>::createMethodCaller();

void (*ptr3)(Test*, int) = MethodCallerFactory<Test, void, int>::Method<&Test::set2>::createMethodCaller();
void (*ptr4)(Test*, INTVALUE) = MethodCallerFactory<Test, void, INTVALUE>::Method<&Test::set2>::createMethodCaller();

void (*ptr5)(Test*, int) = MethodCallerFactory<Test, void, const int>::Method<&Test::set3>::createMethodCaller();
void (*ptr6)(Test*, const INTVALUE) = MethodCallerFactory<Test, void, const INTVALUE>::Method<&Test::set3>::createMethodCaller();

void (*ptr7)(Test*, int&) = MethodCallerFactory<Test, void, int&>::Method<&Test::set4>::createMethodCaller();
void (*ptr8)(Test*, INTREF) = MethodCallerFactory<Test, void, INTREF>::Method<&Test::set4>::createMethodCaller();
}

我得到的唯一错误是在第二个指针声明上:

could not convert template argument ‘&Test::set’ to ‘void (Test::*)(int&)’ void (ptr2)(Test, const INTREF) = MethodCallerFactory::Method<&Test::set>::createMethodCaller();

似乎当我对引用类型使用 typedef 时,编译器忘记了 const 关键字。我不明白为什么会有问题。

最佳答案

我想纯文本替换让您误以为 const INTREF 会解析为 const int&(等同于 int const&),但是替换实际上解析为 int& const,其中 const 最终被忽略(这是唯一的情况,因为涉及 typedef,因为你不能显式声明 int& const 类型的变量)。所以你最终得到的是 int& 而不是 int const&

在代码中:

#include <type_traits>

typedef int& INTREF;

int main()
{
static_assert(std::is_same<const INTREF, int&>{}, "!");
}

Live example

这就是为什么有些人(包括我)更喜欢采用 const-after 样式而不是 const-before 样式的原因之一(这两种样式在技术上是等价的): 除了更加一致,1 它允许通过执行直接的文本替换来理解编译器正在做什么。如果您编写的是 INTREF const 而不是 const INTREF,您可能会得出正确的结论。


1 您不能总是将 const 限定符放在它限定的类型之前,但您总是可以将它放在后面。例如,您可以将类型“指向常量整数的常量指针”拼写为 int const* const(其中 const 关键字始终应用于它之前的所有内容) , 但语法不允许这样写 const const int*; const int* const 是允许的,但它混合了 const-before 和 const-after,从而降低了一致性。

关于c++ - Typedef、模板和 const 关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30545972/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com