可以通过模板函数返回指定类的成员变量吗?

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

Is it possible to return a member variable of a class specified by a template function?

问题

I am trying to generalize a function for a game engine I am writing to simplify the shader loading process.

Anyway, the difficulty arises in my attempts to templating the function. I attempted to adapt the solution found in this stack thread, and resulted in various versions of the following code without any ideal solutions:

  1. template<typename T, typename U, U T::* x>
  2. U testFunc(T& t)
  3. {
  4. // Simplification of the extremely generalized function;
  5. // I want to return/utilize member variable x of input t
  6. return x;
  7. }
  8. struct testS1 { int a = 100; };
  9. struct testS2 { bool b = true; };
  10. testS1 tS1;
  11. testS2 tS2;
  12. // would ideally return 100
  13. int c = testFunc<testS1, int, &testS1::a>(tS1);
  14. // would ideally return true
  15. bool d = testFunc<testS2, bool, &testS2::b>(tS2);

Running the program gives the following error:

  1. Severity: Error
  2. Line: 46
  3. Code: C2440
  4. Description: 'return': cannot convert from 'int testS1::* ' to 'U'

I understand that the returned value x is not the same type as U because int testS1::* is not the same type as int.

However, I do not understand what syntax I would use to return the member variable x of type U from the struct T.

The real structs behind the placeholders testS1 and testS2 are very different from each other, so I would like to avoid using a base class/struct if at all possible.

英文:

I am trying to generalize a function for a game engine I am writing to simplify the shader loading process.

Anyway, the difficulty arises in my attempts to templating the function. I attempted to adapt the solution found in this stack thread, and resulted in various versions of the following code without any ideal solutions:

  1. template&lt;typename T, typename U, U T::* x&gt;
  2. U testFunc(T&amp; t)
  3. {
  4. // Simplification of the extremely generalized function;
  5. // I want to return/utilize member variable x of input t
  6. return x;
  7. }
  8. struct testS1 { int a = 100; };
  9. struct testS2 { bool b = true; };
  10. testS1 tS1;
  11. testS2 tS2;
  12. // would ideally return 100
  13. int c = testFunc&lt;testS1, int, &amp;testS1::a&gt;(tS1);
  14. // would ideally return true
  15. bool d = testFunc&lt;testS2, bool, &amp;testS2::b&gt;(tS2);

Running the program gives the following error:

  1. Severity: Error
  2. Line: 46
  3. Code: C2440
  4. Description: &#39;return&#39;: cannot convert from &#39;int testS1::* &#39; to &#39;U&#39;

I understand that the returned value x is not the same type as U because int testS1::* is not the same type as int.

However, I do not understand what syntax I would use to return the member variable x of type U from the struct T.

The real structs behind the placeholders testS1 and testS2 are very different from each other, so I would like to avoid using a base class/struct if at all possible.

答案1

得分: 4

你只需对 x 进行解引用,就可以获得一个 U

英文:
  1. template&lt;class T, class U, U T::*x&gt;
  2. U testFunc(T&amp; t)
  3. {
  4. return t.*x;
  5. }

You simply need to dereference x to get a U.

答案2

得分: 4

以下是翻译好的部分:

"另一个答案已经提供了访问成员数据指针的语法。在[tag:C++20]中,使用缩写函数模板,你可以以更简洁的方式完成相同的操作。

  1. template&lt;auto x&gt;
  2. constexpr auto testFunc(auto const&amp; t)
  3. {
  4. return t.*x;
  5. }

现在你可以以更简洁的方式调用,不需要明确的模板参数:

  1. int c = testFunc&lt;&amp;testS1::a&gt;(tS1);
  2. bool d = testFunc&lt;&amp;testS2::b&gt;(tS2);
  3. // ...

godbolt.org上查看演示"

英文:

The other answer has already provided the syntax for accessing the pointer to the member data. In [tag:C++20] using abbreviated function template, you could do it, less verbosely the same

  1. template&lt;auto x&gt;
  2. constexpr auto testFunc(auto const&amp; t)
  3. {
  4. return t.*x;
  5. }

Now you call with less explicate template arguments

  1. int c = testFunc&lt;&amp;testS1::a&gt;(tS1);
  2. bool d = testFunc&lt;&amp;testS2::b&gt;(tS2);
  3. // ...

See a demo in godbolt.org

huangapple
  • 本文由 发表于 2023年7月3日 02:00:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76600173.html
匿名

发表评论

匿名网友

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

确定