代码之家  ›  专栏  ›  技术社区  ›  EloiGG

具有任意类型的变量的可数的C++函数

  •  1
  • EloiGG  · 技术社区  · 3 年前

    我刚学会了C++中的变异学,实现了它,但我想知道它是否能做到这一点:

    如果我想要一个参数数量可变的函数,我可以这样做:

            template <typename... Ts>
            f(Ts... args);
    

    但我失去了类型安全性(我不知道参数的类型)。 如果我知道我的功能只需要 浮动 作为论据?我想在编译时确保每个参数都是我想要的类型。

    以下是我的问题:

    • 有没有办法用变量强制某个类型(类似于这样的)?
        template <float... Fs>
        f(Fs... args); // unlimited number of arguments but only float
    
    • 如果没有,有没有办法在编译时检查它?静态断言(std::is_same<A,B>)在大多数情况下都可以,但不适用于模板化类,例如(对于我的用例):
        template <typename T, uint16_t dimension>
        class Vector
        {
            template <typename... Ts>
            Vector(Ts... args)
            {
                static_assert(sizeof...(args) == dimension);
                static_assert(std::is_same_v<Ts..., T>()); //doesn't work because Ts will
                                                           //develop into a lot of template 
                                                           //arguments. Just putting Ts doesn't
                                                           //work either.
            }
        }
    

    Ps:是的,我可以使用std::vector或std::array作为参数,但这不是真正的重点,另外我想保留漂亮的vector(2.0,1.0,0.0)语法,而不是使用大括号。

    谢谢你的回答!

    1 回复  |  直到 3 年前
        1
  •  0
  •   Vlad from Moscow    3 年前

    如果编译器支持C++ 20,那么你可以编写

    #include <type_traits>
    
    template <typename T, uint16_t dimension>
    class Vector
    {
    public:
        template <typename... Ts>
        Vector( Ts &&... args ) requires ( sizeof...( args ) == dimension ) && std::conjunction_v<std::is_same<T, std::decay_t<Ts>>...>
        {
        }
    };
    
    //...
    
    Vector<float, 5> v( 1.1f, 2.2f, 3.3f, 4.4f, 5.5f );
    

    或者作为 @HolyBlackCat 写在评论中,你也可以写

    template <typename T, uint16_t dimension>
    class Vector
    {
    public:
        template <typename... Ts>
        Vector( std::same_as<T> auto ...args ) requires( sizeof...( args ) == dimension )
        {
        }
    };