【问题标题】:How to delete instantiation of a member function template?如何删除成员函数模板的实例化?
【发布时间】:2021-01-15 17:01:26
【问题描述】:

我正在学习如何停止成员函数模板的实例化。在 c++20 中,require 子句用于对模板参数施加约束,使用它我可以在 c++20 中停止实例化。

在这段代码中哪一行代码可以替换c++11/14/17中的requires子句。

#include <iostream>
#include <string>

struct St {
    template<typename T>
    // C++11/14/17 ???
    requires ( !(std::is_same<T, bool>::value || std::is_same<T, std::string>::value)) // C++20
    constexpr auto increment_by_one(T targ) const noexcept { return targ+1; }

};

int main() {
    St s;
    std::cout << s.increment_by_one(5) << '\n';
    std::cout << s.increment_by_one(8.6) << '\n';
    std::cout << s.increment_by_one(6.6f) << '\n';
    //std::cout << s.increment_by_one(true) << '\n';
    //std::cout << s.increment_by_one(std::string("test string")) << '\n';

    return 0;
}

https://gcc.godbolt.org/z/vjc5cE

【问题讨论】:

  • 我不确定你在问什么,但你可能正在寻找std::enable_if
  • 小心将函数声明为noexcept。一旦你这样做了,你就不能在不破坏你的界面的情况下撤销它(有人可能依赖noexcept 保证),你可以把自己画到角落里。如果您的函数最终支持+1 不是noexcept 的类型怎么办?通常析构函数、交换函数和移动构造函数/操作符应该是noexcept。除此之外,添加noexcept 应该是有原因的。不要仅仅因为可以使用它。
  • 我想停止为 bool 和 string 类型实例化成员函数模板“increment_by_one”。

标签: c++ templates c++14


【解决方案1】:

使用类型特征std::enable_if:

#include <type_traits>

// ...

    template<typename T,
        typename std::enable_if<
          !(std::is_same<T, bool>::value || std::is_same<T, std::string>::value),
          int
        >::type = 0
    >
    constexpr auto increment_by_one(T targ) const noexcept -> decltype(targ+1) {
        return targ+1;                                  //    ^^^^^^^^^^^^^^^^
    }                                                   // trailing return type 

请注意,在 C++14 之前,如果您使用 auto,则需要添加尾随返回类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多