【问题标题】:type of input arguments depending on template boolean输入参数的类型取决于模板布尔值
【发布时间】:2022-01-11 21:53:05
【问题描述】:

我的目的很简单,输入的数据类型取决于模板bool:

template<bool isfloa>
class example{
public:
  if (isfloa){
    example(float p){printf("sizeof p: %d\n", sizeof(p))};
  } else{
    example(uint64_t p){printf("sizeof p: %d\n", sizeof(p))};
  }
};

这无法通过编译,我有以下解决方案(尚未测试):

using dataType = isfloa ? float : uint64_t;
example(dataType p){printf("sizeof p: %d\n", sizeof(p))};

我想知道这是否有效?还有其他解决方案吗?非常感谢。

【问题讨论】:

    标签: c++ class templates metaprogramming using


    【解决方案1】:

    您可以使用std::conditional

    template<bool isfloat>
    class example{
    public:
        using value_type = std::conditional_t<isfloat,float,int>;
        example(value_type p){printf("sizeof p: %d\n", sizeof(p));}
    };
    

    【讨论】:

    • 比我的解决方案更好。点赞!
    【解决方案2】:

    在 C++17 中,您可以使用 sfinae 来禁用或启用成员函数:

    template<bool isfloa>
    class example{
    public:
        template<bool isf = isfloa, std::enable_if_t<isf, int> = 0>
        example(float p){ printf("sizeof p: %d\n", sizeof(p)); }
    
        template<bool isf = isfloa, std::enable_if_t<!isf, int> = 0>
        example(uint64_t p){ printf("sizeof p: %d\n", sizeof(p)); }
      }
    };
    

    在 C++20 中,您可以简单地使用 requires 关键字:

    template<bool isfloa>
    class example{
    public:
        example(float p) requires(isfloa)
        { printf("sizeof p: %d\n", sizeof(p)); }
    
        example(uint64_t p) requires(!isfloa)
        { printf("sizeof p: %d\n", sizeof(p)); }
      }
    };
    

    【讨论】:

    • 如果您添加“typename”和“::type”内容,第一个示例也适用于 C++11...
    【解决方案3】:

    更喜欢使用正常的函数重载,然后在需要的地方切换到模板。在这种情况下,对两种浮点类型重复使用相同的代码。

    #include <type_traits> // header file for all kinds of type related checks at compile time
    #include <iostream>
    
    // for std::uint64_t only just use standard overloading 
    // NO need to overuse templates and template specializations where none is needed.
    void example(const std::uint64_t value)
    {
        std::cout << "std::uint64_t, value = " << value << "\n";
    }
    
    // use SFINAE (std::enable_if_t) to enable this version of the function only for floating point types
    template<typename type_t>
    static inline std::enable_if_t<std::is_floating_point_v<type_t>, void> example(const type_t& value)
    {
        std::cout << "floating point value, value = " << value << "\n";
    }
    
    int main()
    {
        double fp{ 3.14159265 };
        example(fp);
    
        std::uint64_t value{ 42 };
        example(value);
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-09
      • 2018-04-09
      • 2012-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多