简体   繁体   English

c++ 模板元编程:如何为我的自定义特征定义类型特征“is_xxxxx_v”别名?

[英]c++ template meta programming: how do you define the type trait "is_xxxxx_v" alias for my custom trait?

So I have been looking through this: https://akrzemi1.wordpress.com/2017/12/02/your-own-type-predicate/所以我一直在看这个: https://akrzemi1.wordpress.com/2017/12/02/your-own-type-predicate/

It shows that you can take a custom trait (or predicate) is_thing<T>::type and alias that to is_thing_t<T> - eg:它表明您可以采用自定义特征(或谓词) is_thing<T>::type并将其别名为is_thing_t<T> - 例如:

template <bool Cond>
using enable_if_t = typename enable_if<Cond>::type;

Now I want to do the same trick to implement the value alias used in other traits.现在我想做同样的技巧来实现其他特征中使用的值别名。 I have a snippet of code below with my attempt:我的尝试下面有一段代码:

// Primary template
// tparam 1 (T) is to pass in the class-under-test. 
// tparam 2 (deafult to void) is to catch all cases not specialised - so they evaluate to false
template <typename T, typename = void>
struct is_really_bob : std::false_type {};

// specialisation
// tparam 1 (T) is to pass in the class-under-test. 
// tparam 2 special meta-function that - if our class best-matches THIS template then it will evaluate to true
template <typename T>
struct is_really_bob <T, std::void_t<
    typename T::result_type,                 // Has a nested type called result_type
    decltype(T::check_bob()),                // Has a static member fn called check_bob
    decltype(std::is_default_constructible_v<T>), // required for below:
    decltype(T{}.set_bob(std::string{""})),  // has member fn set_bob that takes a string (also requires default c'tor)
    decltype(T{}.get_bob())                  // has member fn get_bob (also requires default c'tor)
>> : std::true_type {};

///// THIS FAILS /////
template <bool T>
using is_really_bob_v = typename is_really_bob<T>::value;

The problem here is that ::value is not a type name.这里的问题是::value不是类型名称。 I don't know the syntax to generate a value alias.我不知道生成值别名的语法。 Is there a way to do this?有没有办法做到这一点? I want to end up being able to do something like:我希望最终能够执行以下操作:

if constexpr (is_really_bob_v<T>)
{
    // ...
}

Full code example is here: https://godbolt.org/z/dG11vxesW - not it has the attempt at::value alias commented out so we can at least see the rest of the code working完整的代码示例在这里: https://godbolt.org/z/dG11vxesW - 没有尝试 at::value 别名注释掉所以我们至少可以看到代码工作的 rest

You have two problems in your definition of is_really_bob_v :您对is_really_bob_v的定义有两个问题:

  1. You are declaring it as template <bool T> while the template needs a type.您将其声明为template <bool T>而模板需要一个类型。
  2. You are trying to use a type alias to alias a boolean value.您正在尝试使用类型别名来别名 boolean 值。

It should be它应该是

template <typename T>
//        ^^^^^^^^ not bool
inline constexpr bool is_really_bob_v = is_really_bob<T>::value;
//^^^^^^^^^^^^^^^^^^^no type alias     ^ no typename

Using my above correction the following works as expected:使用我上面的更正,以下工作按预期工作:

struct BobTest {
  BobTest() = default;
  using result_type = bool;

  void set_bob(std::string) {}

  std::string get_bob() { return "bob"; }

  static void check_bob() {}
};

struct NonBobTest {
  NonBobTest() = default;
  // using result_type = bool;

  void set_bob(std::string) {}

  std::string get_bob() { return "bob"; }

  static void check_bob() {}
};

int main() {
  std::cout << "Is BobTest a real bob? " << is_really_bob_v<BobTest> << "\n";
  std::cout << "Is NonBobTest a real bob? "
            << is_really_bob_v<NonBobTest> << "\n";
}

Output: Output:

Is BobTest a real bob? 1
Is NonBobTest a real bob? 0

Since C++14 you can declare variable template as:由于 C++14 您可以将变量模板声明为:

template <typename T>
inline constexpr bool is_really_bob_v = is_really_bob<T>::value;

Before C++14, you can declare it as static data members of a class template, or as return value of a constexpr function template. Before C++14, you can declare it as static data members of a class template, or as return value of a constexpr function template.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM