英文:
In C++ how to reuse a class definition as a different class
问题
假设我们有一个类定义
class Foo {...};
我知道我们可以使用using
或typedef
来重用它的定义
using Bar = Foo; // 或者 typedef Foo Bar;
但它们被视为相同的类型,也就是说编译器将以下内容视为重定义
void fun(const Foo&) { cout<<"It is Foo"<<endl; }
void fun(const Bar&) { cout<<"It is Bar"<<endl; }
是否有可能或有解决方法,可以重用定义,使编译器将它们视为不同的类型?
感谢您的解决方案和讨论
以下是我的情况的一些细节:
类会声明它们的相关类型,而这些类型可以是相同的。
struct MyFoo { using type = SomeRelated; };
struct MyBar { using type = SomeRelated; };
另一个类将使用上述类的相关类型进行构造,我希望构造函数能够区分它们
struct MyClass
{
MyClass(const MyFoo::type&) {cout<<"ctor from MyFoo"<<endl;}
MyClass(const MyBar::type&) {cout<<"ctor from MyBar"<<endl;}
};
英文:
Say we have a class definition
class Foo {...};
I know we can reuse its definition with using
or typedef
using Bar = Foo; // or typedef Foo Bar;
But they are treat as a same type, that is to say the compiler treat following as redefinition
void fun(const Foo&) { cout<<"It is Foo"<<endl; }
void fun(const Bar&) { cout<<"It is Bar"<<endl; }
Is there any possible or work around we can reuse definition that compiler treat as different types
Thanks for your solution and discussion
Here are some details of my case:
classes would declare their related type. and the type could be the same.
struct MyFoo { using type = SomeRelated; };
struct MyBar { using type = SomeRelated; };
Another class would be contructed with the related type of above classes and I want the constructor can distinguish from them
struct MyClass
{
MyClass(const MyFoo::type&) {cout<<"ctor from MyFoo"<<endl;}
MyClass(const MyBar::type&) {cout<<"ctor from MyBar"<<endl;}
};
</details>
# 答案1
**得分**: 4
你可以通过使用类模板来实现,模板实例始终是不同的类型。
```cpp
template <int>
class Impl {
// 在这里实现你的 Foo
};
using Foo = Impl<1>;
using Bar = Impl<2>;
或者使用继承(你不需要记住上面使用的最后一个数字)。
template <typename>
class Impl {
// 在这里实现你的 Foo
};
class Foo : public Impl<Foo> {};
class Bar : public Impl<Bar> {};
英文:
You can make it with help of a class template, template instances are always different types.
template <int>
class Impl {
// Implement like your Foo here
};
using Foo = Impl<1>;
using Bar = Impl<2>;
Or with the inherence (you don't need to recall the last used number above).
template <typename>
class Impl {
// Implement like your Foo here
};
class Foo : public Impl<Foo> {};
class Bar : public Impl<Bar> {};
答案2
得分: 1
这被称为强制类型定义模式/问题。存在许多部分解决方案,但大多数都考虑了基本的C++类型。对于类类型,使用继承更容易:
class foo;
class bar : public foo
{ using foo::foo; }; // 启用所有foo构造函数
对于其他类型,可以使用CRTP和装箱值的组合:
#include <type_traits>
template<typename this_type, typename value_type>
requires(std::is_final_v<value_type> ||
not std::is_class_v<value_type>)
struct strong_alias
{ value_type value; };
struct my_int: strong_alias<my_int,int>{};
my_int i{3};
i.value += 4;
还有其他方法可供选择,但它们通常会导致复杂且难以阅读的代码。
英文:
This is known as the strong typedef idiom/problem. There exist many partial solutions, but mostly fundamental C++ types are considered. For class types, it is easier to use inheritance:
class foo;
class bar : public foo
{ using foo::foo; }; //enable all foo constructors
For other types a combination of CRTP and boxed value can be used:
#include <type_traits>
template<typename this_type, typename value_type>
requires(std::is_final_v<value_type> ||
not std::is_class_v<value_type>)
struct strong_alias
{ value_type value; };
struct my_int: strong_alias<my_int,int>{};
my_int i{3};
i.value += 4;
Other approaches are available too, but they generally lead to complex and hard to read code.
答案3
得分: 0
你无法通过简单地使用重新定义类型来使它们不同。
但是,如果你试图将相同类型传递给同名但具有不同实现的函数,请调整函数参数签名。试用以下代码:
#include <iostream>
class foo {
};
void test(const foo&) { std::cout << "void test(const foo&)\n"; }
void test(const foo&, int) { std::cout << "void test(const foo&, int)\n"; }
int main() {
foo f;
test(f);
test(f, 0);
return 0;
}
英文:
You cannot make them different by simply using re-define-type.
But if you are trying to pass same type to functions having same name but different implementation, give a tuning to function parameter signature. Try the code below.
#include <iostream>
class foo {
};
void test(const foo&) { std::cout << "void test(const foo&)\n"; }
void test(const foo&, int) { std::cout << "void test(const foo&, int)\n"; }
int main() {
foo f;
test(f);
test(f, 0);
return 0;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论