【发布时间】:2020-10-11 19:46:59
【问题描述】:
我正在尝试创建一个获取和设置的类,具体取决于它是否传递了 getter 和 setter,或者只是一个指向要获取和设置的变量的指针。这个想法是,当它使用指针参数构造时, TGetter 和 TSetter 成员只是默认为 chars 并且不做任何事情。如果使用 setter 和 getter 构造函数调用它,则指向变量的指针默认为 char 并且不执行任何操作。我尝试使用带有 typedefs 的 std::enable_if 来确定 T 是什么,但我得到了多个定义:
template <typename TGetter = char, typename TSetter = char, typename Tptr = char>
struct GetterSetter
// IF THE PTR CONSTRUCTOR IS CALLED THEN I WANT T TO BE THE TYPE OF TGetter() called result.
// IF THE GETTER AND SETTER CONSTRUCTOR IS CALLED I WANT T TO BE THE TYPE OF
// T DEREFERENCED
{
typedef std::enable_if<std::is_same_v<Tptr, char>, std::invoke_result_t<TGetter>> T;
typedef std::enable_if < std::is_same_v<TGetter, char>, std::remove_pointer_t<Tptr>> T;
GetterSetter(TGetter getter, TSetter setter) : getter(getter), setter(setter) {}
GetterSetter(Tptr ptr) : ptrToT(ptr) {}
TGetter getter;
TSetter setter;
Tptr ptrToT;
T get()
{
if constexpr (std::is_same_v<Tptr, char>) return *ptrToT;
else return getter();
}
void set(T t)
{
if constexpr (std::is_same_v<Tptr, char>) *ptrToT = t;
else setter(t);
}
};
如何预防?我根本没有实例化这个类,我得到了重新定义编译器错误。
【问题讨论】:
-
std::enable_if-base 将 SFINAE 与函数重载解析一起使用。没有 typedef 的重载决议之类的东西。仅适用于函数和类。 -
你不能根据你如何构造一个类的object来选择一个类成员。 T 是该类的成员。它独立于任何对象而存在。
-
按照我看到的编写方式,代码总是使用 getter 和 setter,但它的构造函数接受适当类型的指针并创建适当的 lambdas 用作它的 getter 和 setter。这似乎比试图弄乱不同的
typedefs 要干净一些。 -
@Nathan Pierson 是的,我认为这在课堂上可能更干净,但是无论何时调用它,GetterSetter(&myvariable);和 GetterSetter( [ ] {return myvariable;}, [] (int i) { myvariable = i;});
-
您可以仅通过
T对类进行参数化,然后您可以使用std::function<T(void)> getter;而不是TGetter getter;。您编写一个接受T*并生成适当 lambda 的 ctor,然后编写一个直接采用 getter 和 setter 函数的 ctor 重载。调用代码仍然看起来像getterSetter.get()和getterSetter.set(newValue)。