94153


例えば次のコードの様に、`long`の完全特殊化が存在するクラステンプレートを`int`で実体化したとき、プライマリテンプレートが選択されることは保証されているのでしょうか？

[code]

    #include <iostream>
    
    template <typename T>
    struct A
    {
        A()
        {
            std::cout << "primary" << std::endl;
        }
    };
    
    template <>
    struct A<long>
    {
        A()
        {
            std::cout << "specialized" << std::endl;
        }
    };
    
    int main()
    {
        A<int> b2;
    }
    
[/code]

**出力**

[code]

    primary
    
[/code]

上記のような出力になることを期待して今まで実装していたのですが、よく考えてみるとこれが定義された動作なのかわかりませんでした。

[C++11ドラフト](https://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf)の

> 14.7 Template instantiation and specialization

や  
[cppreference.comのテンプレート関連](https://ja.cppreference.com/w/cpp/language/templates)  
を出来る限り読んでみたのですが、力尽きました！  
よろしくお願いします。


CC BY-SA 4.0
2023-03-13T06:22:23.460
94151
2023-03-13T07:19:19.823
44647
question
c++
型テンプレート引数で暗黙の型変換が考慮されないことは保証されていますか？


引用はいいんようってことで条文や章節番号などは `JIS X3014:2003`

多分気にしているのは標準変換 `4` 特に汎整数昇格 `4.5` のことで `func(long)` を `func(0)` （ここで引数の型は
`long` ではなく `int` ）と呼び出せるってのと混乱しているのでしょうが、汎整数昇格は `rvalue`
に対して暗黙に行われるのでこの例のように型名が明示されているときには発生しません。

`template` の型解決の場合も汎整数昇格よりは `13.3.1` や `13.3.2` や `13.3.3`
あたりの候補関数選定ロジックのほうが優先的に判断されるので特に問題にならないはずっス。

[code]

    #include <iostream>
    
    template<typename T> struct A {
        A(T) { std::cout << "primary" << std::endl; }
    };
    template<> struct A<long> {
        A(long) { std::cout << "long" << std::endl; }
    };
    template<> struct A<short> {
        A(short) { std::cout << "short" << std::endl; }
    };
    template<> struct A<char> {
        A(char) { std::cout << "char" << std::endl; }
    };
    template<> struct A<int> {
        A(int) { std::cout << "int" << std::endl; }
    };
    
    int main()
    {
        A a1(0);
        A a2('\0');
        A a3(0L);
        A a4(0U);
    }
    
[/code]

特殊化の一部をコメント化したり引数の値をサフィックスで型明示して動きを調べてみてください。


CC BY-SA 4.0
2023-03-13T07:19:19.823
94153
2023-03-13T07:19:19.823
8589
94151
answer