【问题标题】:how to set a default arguments for a generic template class如何为通用模板类设置默认参数
【发布时间】:2021-01-27 13:51:26
【问题描述】:

我正在尝试实现一个通用模板类。我希望使用 3 个整数 {0,0,0} 的 std::array 实例化该类的默认元素,但是,我不知道如何放置默认参数列表。 我的目标:

Vec<> a; -> 创建一个带有数组 {0,0,0} 作为私有成员的 vec3

Vec<int,3> b; -> 同上

Vec<int,2> c; -> 创建一个带有数组 {0,0} 的 vec

Vec<double,3> d(4,5,9); -> 创建一个以 {4,5,9} 作为双精度的 vec

我的代码, vec.h

template<typename T = int, int N = 3>
class Vec{
public:
    Vec(T v0,T v1) : vec_coordinates_ ({v0,v1} = {0,0}){
        static_assert(N == 2, "wrong number of arguments");
    };
    Vec(T v0,T v1,T v2) : vec_coordinates_ ({v0,v1,v2}){
        static_assert(N == 3, "wrong number of arguments");
    };

    private:
     std::array<T,N> vec_coordinates_;
 }

不编译。 具有两个元素的数组的构造函数有效。

Vec(T v0,T v1) : vec_coordinates_ ({v0,v1} = {0,0}) {
static_assert(N == 2, "wrong number of arguments");};

上面的编译,但是

    Vec3(T v0,T v1,T v2) : vec_coordinates_ ({v0,v1,v2} = {0,0,0}) { //C2059
    static_assert(N == 3, "wrong number of arguments");
    };

不编译。我得到了错误:

错误 C2059:语法错误:'='

与 {0,0,0} 一致。

我不明白其中的区别,为什么 {0,0} 可以编译而带有 3 个零的数组却没有。如果您有任何提示或建议,我将不胜感激。

【问题讨论】:

  • ({v0,v1} = {0,0}) 应该做什么?
  • 应该保证 Vec b;将导致 a 对象 b 具有 vec_coordinates_ 的私有 std::array 等于 {0,0}

标签: c++ templates


【解决方案1】:

您可以使用std::initializer_list 来完成它。

#include <array>
#include <initializer_list>

template<typename T = int, int N = 3>
class Vec {
    /**
     * You can have this here. 
     * Its neat and for people who goes through this object it'll be easy for them to understand.
     * Also you don't have to have one of this in every constructor this way.
     */
    static_assert(N == 2, "wrong number of arguments");

public:
    /**
     * Default constructor.
     * This sets the array's values to 0.
     */
    Vec() {
        std::memset(vec_coordinates_.data(), 0, sizeof(T) * N);
    }

    Vec(std::initializer_list<T> list) {
        std::memcpy(vec_coordinates_.data(), list.begin(), sizeof(T) * N);
    };

private:
    std::array<T, N> vec_coordinates_;
};

int main()
{
    Vec<int, 2> a = { 0, 1 };
}

我不明白其中的区别,为什么 {0,0} 可以编译而带有 3 个零的数组却没有。如果您有任何提示或建议,我将不胜感激。

你知道{v0,v1,v2} = {0,0,0}{v0,v1} = {0,0} 发生了什么吗?您尝试做的是在 C++ 中不允许做的事情。您将 lvalue 分配给另一个 lvalue 并将其分配给变量。换句话说,你所做的是这样的:

int i = 10 = 10;

现在你明白为什么会出现错误了吗?

【讨论】:

  • 还有一件事 - 如何为使用初始化列表生成的对象放置默认值?这样 Vec b;解析为 {0,0} ?
【解决方案2】:

怎么样


template<typename T = int, int N = 3>
class Vec{
public:
    Vec(T v0 = 0,T v1 = 0) : vec_coordinates_ ({v0,v1}){
        static_assert(N == 2, "wrong number of arguments");
    };
    Vec(T v0 = 0,T v1 = 0,T v2 = 0) : vec_coordinates_ ({v0,v1,v2}){
        static_assert(N == 3, "wrong number of arguments");
    };

    private:
     std::array<T,N> vec_coordinates_;
 };

另外,据我所知, std:array 会自动用“零”初始化自己(实际上可能取决于编译器),所以添加空构造函数应该可以解决问题(+你没有担心是否有人使用了一些奇怪的T)

【讨论】:

    猜你喜欢
    • 2016-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    • 2013-02-28
    相关资源
    最近更新 更多