Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
75 views
in Technique[技术] by (71.8m points)

c++ - how to set a default arguments for a generic template class

I am trying to implement a generic template class. I would like the default element of the class to be instantiated with std::array of 3 ints {0,0,0} however, I don't know how to place the default list of arguments. My goal:

Vec<> a; -> creates a vec3 with an array {0,0,0} as private member

Vec<int,3> b; -> the same as above

Vec<int,2> c; -> creates a vec with array {0,0}

Vec<double,3> d(4,5,9); -> creates a vec with {4,5,9} as doubles

My code, 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_;
 }

doesn't compile. The constructor for an array with two elements works.

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

The above compiles, however

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

does not compile. I get the error:

error C2059: syntax error: '='

on the line with {0,0,0}.

I don't understand the difference, why the {0,0} compiles and the array with 3 zeros doesn't. I would be very grateful for any tips or pieces of advice.

question from:https://stackoverflow.com/questions/65920543/how-to-set-a-default-arguments-for-a-generic-template-class

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can use std::initializer_list to get it done.

#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 };
}

I don't understand the difference, why the {0,0} compiles and the array with 3 zeros doesn't. I would be very grateful for any tips or pieces of advice.

Do you understand what's happening in {v0,v1,v2} = {0,0,0} and {v0,v1} = {0,0}? What your trying to do is something which is not allowed to do in C++. Your assigning a lvalue to another lvalue and assign it to a variable. In other words, what you have done is something like this:

int i = 10 = 10;

Now you see why the error comes?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...