gartenriese
gartenriese

Reputation: 4356

Templates and std::pair list-initialization

This is a follow-up to this question.

Why does this compile:

#include <iostream>
class Test {
    public:
        Test(std::pair<char *, int>) {
            std::cout << "normal constructor 2!" << std::endl;
        }
};

int main() {
    Test t6({"Test", 42});
    return 0;
}

But this does not:

#include <iostream>
class Test {
    public:
        Test(std::pair<char *, int>) {
            std::cout << "normal constructor 2!" << std::endl;
        }
        template<typename ... Tn>
        Test(Tn ... args) {
            std::cout << "template constructor!" << std::endl;
        }
};

int main() {
    Test t6({"Test", 42});
    return 0;
}

Error message:

error: call to constructor of 'Test' is ambiguous

As I understood in the previous question, the non-template constructor is preferred, if it exactly matches. So I guess {"Test", 42} does not match with std::pair? If so, what would be the correct way? I know there is std::make_pair, but I want it as short as possible, because I can have several of those pairs and typing std::make_pair everytime would be unfavorable, because it bloats things. So what is the shortest way possible?

Upvotes: 2

Views: 1802

Answers (1)

markd
markd

Reputation: 218

Since you're already using c++11, switch to brace initialization and your code will compile under gcc (4.7.2 at least) and do what you want:

...
int main() {
    Test t6{{"Test", 42}};
    return 0;
}

$ g++ t.cpp -std=c++11
t.cpp: In function ‘int main()’:
t.cpp:14:25: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

$ a.out
normal constructor 2!

Upvotes: 3

Related Questions