如何在不知道模板数据类型的情况下定义一个静态模板变量?

huangapple go评论86阅读模式
英文:

How can I define a static templated variable without knowing the template data type?

问题

以下是您要翻译的内容:

让我们假设我有以下结构体来存储对类成员变量的引用:

```cpp
template <typename R>
struct Foo {
    R ref;
    int info;
};
class Bar {
public:
    void* run();
};

我想创建一个类型为Foo的常量变量,立即将ref参数设置如下:

const Foo theVar {&Bar::run, 0x1000}; //不起作用,但更可取
const Foo<void (Bar::*)()> theVar {&Bar::run, 0x1000}; //起作用,但不太理想

在这种情况下我使用模板的原因是因为没有办法将类成员变量转换为void*,所以我被迫采用这种方式。然而,似乎我不能在告诉编译器我计划使用的类型之前声明变量。虽然我有这个信息,但这不是实现我想要的方式,可能会在长期内引发一些问题。

编译器应该能够识别我正在向这个结构体传递类型为void (Bar::*)()的变量,所以我几乎可以确定一定有方法解决这个问题。

我需要这个结构体的原因是因为我需要一个引用供链接器使用。我不希望它在运行时设置,它需要在链接器中可用。使用模板似乎是唯一的解决方法。


<details>
<summary>英文:</summary>

Let&#39;s say I have the following struct to store a reference to a class member variable:

template <typename R>
struct Foo {
R ref;
int info;
};
class Bar {
public:
void* run();
};


I want to create a const variable of type foo that immediately sets the ref param as follows:

const Foo theVar {&Bar::run, 0x1000}; //Doesn't work, but preferred
const Foo<void (Bar::*)()> theVar {&Bar::run, 0x1000}; //Does work, but rather not


The reason I&#39;m using a template in this case is because there&#39;s no way to cast a class member variable to a `void*`, so I&#39;m forced into this position. However, it seems that I cannot declare the variable without first telling the compiler what type I&#39;m planning to use. Although I do have this information, it&#39;s not the prettiest way to accomplish what I want and could possibly cause some issues in the long run. 

The compiler should be able to tell that I&#39;m passing a variable of type `void (Bar::*)()` to this struct, so I&#39;m almost certain there has to be a way around this issue. 

The reason I&#39;m in need of this struct is because I need a reference to exist for the linker. I don&#39;t want it to be set on run-time, it needs to be available for the linker. Using templates seems to be the only way to accomplish this.

</details>


# 答案1
**得分**: 3

解决方法很简单:在`Foo`声明后添加一个[推导指南](https://en.cppreference.com/w/cpp/language/class_template_argument_deduction#Deduction_for_class_templates):
```cpp
template<typename R>
struct Foo {
    R ref;
    int info;
};

template<typename R> Foo(R, int) -> Foo<R>;

演示

英文:

The solution is simple: add a deduction guide after Foo declaration:

template&lt;typename R&gt;
struct Foo {
    R ref;
    int info;
};

template&lt;typename R&gt; Foo(R, int) -&gt; Foo&lt;R&gt;;

Demo

huangapple
  • 本文由 发表于 2023年1月9日 06:17:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75051651.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定